27 #include <Classes.hpp>
28 #include <Controls.hpp>
29 #include <StdCtrls.hpp>
31 #include <Buttons.hpp>
32 #include <ExtCtrls.hpp>
34 #include <Dialogs.hpp>
35 #include <Graphics.hpp>
36 #include <ComCtrls.hpp>
59 #include <Filectrl.hpp>
62 #include <Vcl.HTMLHelpViewer.hpp>
63 #pragma package(smart_init)
64 #pragma link "Vcl.HTMLHelpViewer" //added at v2.0.0 for access to the .chm help file
65 #pragma resource "*.dfm"
84 Screen->Cursor = TCursor(-11);
150 "program operation may be restricted");
160 Application->HelpFile = AnsiString(
CurDir +
"\\Help.chm");
168 int DispW = (Screen->Width - 64) / 16;
169 int DispH = (Screen->Height - 192) / 16;
173 Display =
new TDisplay(
MainScreen,
PerformanceLogBox,
OutputLog1,
OutputLog2,
OutputLog3,
OutputLog4,
OutputLog5,
OutputLog6,
OutputLog7,
OutputLog8,
311 SpeedButton96->Glyph->LoadFromResourceName(0,
"ConcourseGlyph");
375 FontButton->Glyph->LoadFromResourceName(0,
"FontGraphic");
376 HomeButton->Glyph->LoadFromResourceName(0,
"Home");
395 SetGapsButton->Glyph->LoadFromResourceName(0,
"ConnectGaps");
406 CallOnImage->Picture->Bitmap->LoadFromResourceName(0,
"CallingOn");
407 CrashImage->Picture->Bitmap->LoadFromResourceName(0,
"CrashWarning");
408 DerailImage->Picture->Bitmap->LoadFromResourceName(0,
"DerailWarning");
409 SignalStopImage->Picture->Bitmap->LoadFromResourceName(0,
"SignalStopWarning");
410 SPADImage->Picture->Bitmap->LoadFromResourceName(0,
"SPADWarning");
411 TrainFailedImage->Picture->Bitmap->LoadFromResourceName(0,
"TrainFailedWarning");
413 DistanceKey->Picture->Bitmap->LoadFromResourceName(0,
"DistanceKey");
414 PrefDirKey->Picture->Bitmap->LoadFromResourceName(0,
"PrefDirKey");
416 TrackLinkedImage->Picture->Bitmap->LoadFromResourceName(0,
"TrackLinkedGraphic");
418 GapsNotSetImage->Picture->Bitmap->LoadFromResourceName(0,
"GapsNotSetGraphic");
419 GapsSetImage->Picture->Bitmap->LoadFromResourceName(0,
"GapsSetGraphic");
443 AnsiString NL =
'\n';
444 const AnsiString TTLabelStr1 =
"Start new train" + NL +
"Start new service from a split" + NL +
"Start new service from another service" + NL +
445 "Start new non-repeating shuttle finish service" + NL +
"Start new shuttle train at a timetabled stop" + NL +
446 "Start new shuttle service from a feeder";
448 const AnsiString TTLabelStr2 =
"Pass" + NL +
"Be joined by another train" + NL +
"Front split" + NL +
"Rear split" + NL +
"Change direction of train";
450 const AnsiString TTLabelStr3 =
"Finish && form a new service" + NL +
"Finish && join another train" + NL +
"Finish && exit railway" + NL +
451 "Finish && repeat shuttle, finally remain here" + NL +
"Finish && repeat shuttle, finally form a finishing service" + NL +
452 "Finish non-repeating shuttle feeder service" + NL +
"Finish && remain here";
454 const AnsiString TTLabelStr4 =
"HH:MM" + NL +
"HH:MM" + NL +
"HH:MM" + NL +
"HH:MM" + NL +
"HH:MM" + NL +
"HH:MM" + NL +
"HH:MM" + NL +
"HH:MM" + NL +
455 "HH:MM" + NL +
"HH:MM" + NL +
"HH:MM" + NL +
"HH:MM" + NL +
"HH:MM" + NL +
"HH:MM" + NL +
"HH:MM" + NL +
"HH:MM" + NL +
"HH:MM" + NL +
" " + NL +
"R";
457 const AnsiString TTLabelStr5 =
"HH:MM ';' Location" + NL +
"HH:MM ';' HH:MM ';' Location";
459 const AnsiString TTLabelStr6 =
"+ rear element ID - space - front element ID [+ optional ';S']" + NL +
"+ ref. of the train that splits" + NL +
460 "+ other service ref." + NL +
"+ shuttle service ref." + NL +
"+ rear element ID - space - front element ID ';' linked shuttle ref." + NL +
461 "+ linked shuttle service ref. ';' feeder service ref." + NL +
"+ location" + NL +
"+ joining train ref." + NL +
"+ new service ref." + NL +
462 "+ new service ref." + NL +
" " + NL +
"+ new service ref." + NL +
"+ ref. of train to join" + NL +
463 "+ list of valid exit element IDs (at least 1) separated by spaces" + NL +
"+ linked shuttle service ref.";
465 const AnsiString TTLabelStr7 =
"Arrival OR departure time (program will determine which from the context) + location." + NL +
466 "Arrival time, departure time (with no events between) + location";
468 const AnsiString TTLabelStr9 =
"Timetable entries" + NL +
"(service references etc.)";
469 const AnsiString TTLabelStr11 =
"Timetable" + NL +
"start time";
471 const AnsiString TTLabelStr12 =
"NB: WITHIN SERVICES commas must" + NL +
"not be used (have special meanings)," + NL +
472 "and semicolons may only be used to" + NL +
"separate service components.";
474 const AnsiString TTLabelStr13 =
"+ linked shuttle service ref. ';' finishing service ref." + NL +
"+ linked shuttle service ref.";
476 const AnsiString TTLabelStr15 =
"Repeat the service + ';' minutes between repeats ';' digit increment ';' number of repeats (last line of service)";
493 AnsiString ColourStr =
"";
494 std::ifstream ColFile((
CurDir +
"\\Background.col").c_str());
505 else if((ColourStr !=
"white") && (ColourStr !=
"black") && (ColourStr !=
"blue"))
511 if(ColourStr ==
"white")
515 else if(ColourStr ==
"blue")
528 AnsiString RHSigStr =
"";
529 std::ifstream SignalFile((
CurDir +
"\\Signal.hnd").c_str());
530 if(SignalFile.fail())
532 SigImagePanel->Caption =
"Signals will be on the left hand side of the track";
538 std::ofstream SignalFile((
CurDir +
"\\Signal.hnd").c_str());
539 if(!SignalFile.fail())
549 if(RHSigStr ==
"RHSignals")
561 SigImagePanel->Caption =
"Signals will be on the right hand side of the track";
571 SigImagePanel->Caption =
"Signals will be on the left hand side of the track";
577 std::ofstream SignalFile((
CurDir +
"\\Signal.hnd").c_str());
578 if(!SignalFile.fail())
596 std::ifstream SplashFile((
CurDir +
"\\GNU").c_str());
597 if(SplashFile.fail())
600 "This program is free software released under the terms of the GNU General Public License Version 3, as published by the Free Software Foundation. It may be used or redistributed in accordance with that license and is released in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details - you should have received a copy along with this program but if not see <http://www.gnu.org/licenses/>.");
601 std::ofstream SplashFile((
CurDir +
"\\GNU").c_str());
602 if(!SplashFile.fail())
606 if((Screen->Width < 1024) || (Screen->Height < 768))
608 ShowMessage(
"Please note that this program works best with a screen resolution of at least 1024 x 768. Please change if possible");
614 WindowState = wsMaximized;
626 Screen->Cursor = TCursor(-2);
654 char *LocalNumericInformation = setlocale(LC_NUMERIC,
"");
656 if(LocalNumericInformation ==
"")
661 struct lconv *conv = &Locale;
667 catch(
const EFOpenError &e)
671 MessageDlg(e.Message +
" - program must terminate", mtError, But, 0);
672 Application->Terminate();
675 catch(
const Exception &e)
679 AnsiString Message =
"A fatal error occurred during the program setup process, the program must terminate. Message = " + e.Message;
680 MessageDlg(Message, mtError, But, 0);
682 Application->Terminate();
712 catch(
const Exception &e)
728 catch(
const Exception &e)
747 Screen->Cursor = TCursor(-2);
757 Screen->Cursor = TCursor(-2);
764 catch(
const Exception &e)
781 catch(
const Exception &e)
794 UnicodeString strVersion = L
"N/A";
796 VersionSize = GetFileVersionInfoSizeW(Application->ExeName.c_str(), &VersionHandle);
799 pBuffer =
new BYTE[VersionSize];
801 if(GetFileVersionInfoW(Application->ExeName.c_str(), VersionHandle, VersionSize, pBuffer))
803 VS_FIXEDFILEINFO *fi;
807 if(VerQueryValueW(pBuffer, L
"\\", (
void**)&fi, &buflen))
810 strVersion.sprintf(L
"%d.%d.%d", HIWORD(fi->dwFileVersionMS), LOWORD(fi->dwFileVersionMS), HIWORD(fi->dwFileVersionLS)
819 return L
" v" + strVersion;
835 catch(
const Exception &e)
854 catch(
const Exception &e)
867 if(((TSpeedButton*)Sender)->Down)
879 catch(
const Exception &e)
913 ShowMessage(
"Incomplete track or other error - see inverted element (may be behind this message)");
924 ShowMessage(
"Unable to set any track links");
937 ShowMessage(
"Successful Completion");
953 catch(
const Exception &e)
974 catch(
const Exception &e)
993 catch(
const Exception &e)
1012 catch(
const Exception &e)
1031 TFont *TempFont =
new TFont;
1039 TempText.
Font = DisplayFont;
1046 else if(Key ==
'\x1B')
1052 catch(
const Exception &e)
1071 catch(
const Exception &e)
1086 ShowMessage(
"Error, location name being entered without an entry in LNPendingList");
1106 Screen->Cursor = TCursor(-11);
1108 AnsiString ExistingName;
1115 UnicodeString MessageStr = UnicodeString(
"Another location named '") +
LocationNameTextBox->Text +
1116 UnicodeString(
"' already exists. If you continue its name will be erased. Do you wish to continue?");
1117 int button = Application->MessageBox(MessageStr.c_str(), L
"Warning!", MB_YESNO | MB_ICONWARNING);
1121 Screen->Cursor = TCursor(-2);
1132 bool UseExistingPosition =
false;
1139 if(ExistingName !=
"")
1142 UseExistingPosition =
true;
1145 Screen->Cursor = TCursor(-2);
1159 bool UseExistingPosition =
false;
1161 UseExistingPosition =
true;
1164 Screen->Cursor = TCursor(-2);
1176 LocStr = LocStr.Trim();
1185 if((LocStr !=
"") && (LocStr[1] >=
'0') && (LocStr[1] <=
'9'))
1187 Screen->Cursor = TCursor(-2);
1188 ShowMessage(
"Location name can't begin with a number");
1196 if(LocStr.Length() > 50)
1198 Screen->Cursor = TCursor(-2);
1199 ShowMessage(
"Location name too long, 50 characters maximum");
1207 for(
int x = 1; x <= LocStr.Length(); x++)
1209 char Ch = LocStr[x];
1210 if((Ch !=
' ') && (Ch !=
'&') && (Ch !=
'(') && (Ch !=
')') && (Ch !=
':') && (Ch != 39) && (Ch !=
'.') && (Ch !=
'-') && (Ch !=
'+') &&
1211 (Ch !=
'/') && ((Ch <
'0') || (Ch >
'9')) && ((Ch <
'A') || (Ch >
'Z')) && ((Ch <
'a') || (Ch >
'z')))
1213 Screen->Cursor = TCursor(-2);
1215 "Location name contains one or more invalid characters, must be alphanumeric, brackets, space, full stop, colon, inverted comma, '-', '+', '/' or '&&'");
1226 Screen->Cursor = TCursor(-2);
1227 ShowMessage(
"Location name cannot be 'cdt', this name would interfere with the timetable");
1238 bool UseExistingPosition =
false;
1239 if(ExistingName !=
"")
1242 UseExistingPosition =
true;
1245 Screen->Cursor = TCursor(-2);
1254 Screen->Cursor = TCursor(-2);
1257 catch(
const Exception &e)
1278 catch(
const Exception &e)
1291 int Dist = 0, SpeedLimit = 0;
1294 DistanceStr =
"No change";
1297 SpeedStr =
"No change";
1300 if(DistanceStr ==
"No change")
1302 if(SpeedStr ==
"No change")
1312 if(((Dist != -1) && (DistanceStr.Length() > 6)) || ((SpeedLimit != -1) && (SpeedStr.Length() > 6)))
1314 ShowMessage(
"One or more entries too long");
1318 if((DistanceStr ==
"") || (SpeedStr ==
""))
1320 ShowMessage(
"One or more entries blank");
1326 for(
int x = 1; x <= DistanceStr.Length(); x++)
1328 if((DistanceStr[x] <
'0') || (DistanceStr[x] >
'9'))
1330 ShowMessage(
"Track length value must be a positive whole number, or blank for no change");
1338 for(
int x = 1; x <= DistanceStr.Length(); x++)
1340 if((DistanceStr[x] <
'0') || (DistanceStr[x] >
'9'))
1342 ShowMessage(
"Distance must be a positive whole number");
1350 for(
int x = 1; x <= SpeedStr.Length(); x++)
1352 if((SpeedStr[x] <
'0') || (SpeedStr[x] >
'9'))
1354 ShowMessage(
"Speed limit must be a positive whole number, or blank for no change");
1362 for(
int x = 1; x <= SpeedStr.Length(); x++)
1364 if((SpeedStr[x] <
'0') || (SpeedStr[x] >
'9'))
1366 ShowMessage(
"Speed limit must be a positive whole number, or 'Mixed'");
1373 Dist = DistanceStr.ToInt();
1374 if(SpeedLimit != -1)
1375 SpeedLimit = SpeedStr.ToInt();
1383 if(((Dist != -1) && (Dist < 20)) || ((SpeedLimit != -1) && (SpeedLimit < 10)) || ((SpeedLimit != -1) && (SpeedLimit >
TTrain::MaximumSpeedLimit)))
1386 ShowMessage(
"Lengths must be 20m or more, and speeds must be between 10km/h and 400km/h");
1399 bool NamedLocPresent =
false;
1402 for(
int x = LowSelectHLoc; x < HighSelectHLoc; x++)
1404 for(
int y = LowSelectVLoc; y < HighSelectVLoc; y++)
1407 NamedLocPresent =
true;
1411 if(NamedLocPresent && (Dist < 50))
1413 ShowMessage(
"Note: Named location elements are quite short. If they are too short the simulation might depart too far from reality.");
1416 if(NamedLocPresent && (Dist > 200))
1418 ShowMessage(
"Note: Named location elements are quite long. If they are too long the simulation might depart too far from reality.");
1421 for(
int x = LowSelectHLoc; x < HighSelectHLoc; x++)
1423 for(
int y = LowSelectVLoc; y < HighSelectVLoc; y++)
1460 catch(
const Exception &e)
1483 catch(
const Exception &e)
1495 TMsgDlgButtons Buttons;
1496 Buttons << mbYes << mbNo;
1497 if(MessageDlg(
"This will reset the selected elements to default lengths & speed limits. Proceed?", mtWarning, Buttons, 0) == mrNo)
1515 for(
int x = LowSelectHLoc; x < HighSelectHLoc; x++)
1517 for(
int y = LowSelectVLoc; y < HighSelectVLoc; y++)
1571 throw Exception(
"Error, XLinkPos > 1 in SetOneDefaultTrackLength at " + AnsiString(TrackElement.
HLoc) +
" & " +
1572 AnsiString(TrackElement.
VLoc));
1588 catch(
const Exception &e)
1600 TMsgDlgButtons Buttons;
1601 Buttons << mbYes << mbNo;
1602 if(MessageDlg(
"This will reset ALL track elements to default lengths & speed limits. Proceed?", mtWarning, Buttons, 0) == mrNo)
1623 catch(
const Exception &e)
1651 bool GraphicFoundInVector =
false;
1652 for(TTrack::TUserGraphicVector::iterator UGVIt =
Track->
UserGraphicVector.begin(); UGVIt < Track->UserGraphicVector.end(); UGVIt++)
1654 if(UGMIt->first == UGVIt->FileName)
1656 GraphicFoundInVector =
true;
1660 if(!GraphicFoundInVector)
1662 delete UGMIt->second;
1678 catch(
const Exception &e)
1718 catch(
const Exception &e)
1757 catch(
const Exception &e)
1781 catch(
const Exception &e)
1807 catch(
const Exception &e)
1826 catch(
const Exception &e)
1841 ShowMessage(
"No preferred direction selection");
1845 Screen->Cursor = TCursor(-11);
1850 Screen->Cursor = TCursor(-2);
1853 catch(
const Exception &e)
1866 TMsgDlgButtons Buttons;
1867 Buttons << mbYes << mbNo;
1868 if(MessageDlg(
"Do you really want to clear all preferred directions?", mtWarning, Buttons, 0) == mrNo)
1884 catch(
const Exception &e)
1899 Screen->Cursor = TCursor(-11);
1908 Screen->Cursor = TCursor(-2);
1911 catch(
const Exception &e)
1929 catch(
const Exception &e)
1950 catch(
const Exception &e)
1975 catch(
const Exception &e)
1999 InfoPanel->Caption =
"PRE-START: Select AUTOMATIC SIGNAL ROUTE start signal, or left click points to change manually";
2001 InfoPanel->Caption =
"OPERATING: Select AUTOMATIC SIGNAL ROUTE start signal, or left click points to change manually";
2009 catch(
const Exception &e)
2033 InfoPanel->Caption =
"PRE-START: Select PREFERRED ROUTE start signal, or left click points to change manually";
2035 InfoPanel->Caption =
"OPERATING: Select PREFERRED ROUTE start signal, or left click points to change manually";
2043 catch(
const Exception &e)
2073 InfoPanel->Caption =
"PRE-START: Select UNRESTRICTED ROUTE start location, or left click points to change manually";
2075 InfoPanel->Caption =
"OPERATING: Select UNRESTRICTED ROUTE start location, or left click points to change manually";
2083 catch(
const Exception &e)
2098 InfoPanel->Caption =
"ROUTE CANCELLING: Right click on truncate element, first element to cancel (anywhere else to skip)";
2105 catch(
const Exception &e)
2132 catch(
const Exception &e)
2147 UnicodeString MessageStr =
"Please note that the session will be lost if it hasn't been saved. Do you still wish to exit?";
2150 int button = Application->MessageBox(MessageStr.c_str(), L
"Please confirm", MB_YESNO);
2188 catch(
const Exception &e)
2225 catch(
const Exception &e)
2237 Screen->Cursor = TCursor(-11);
2238 std::ifstream VecFile(LoadFileName.c_str());
2239 if(!(VecFile.fail()))
2244 bool GraphicsFollow =
false;
2263 TFont *TempFont =
new TFont;
2264 TempFont->Style.Clear();
2265 TempFont->Name =
"MS Sans Serif";
2266 TempFont->Size = 10;
2268 TempFont->Charset = (TFontCharset)(0);
2277 if((LeftExcess > 0) && (RightExcess > 0))
2279 else if((LeftExcess > 0) && (RightExcess <= 0))
2282 else if((LeftExcess <= 0) && (RightExcess > 0))
2290 if((TopExcess > 0) && (BotExcess > 0))
2292 else if((TopExcess > 0) && (BotExcess <= 0))
2295 else if((TopExcess <= 0) && (BotExcess > 0))
2307 if((LastChar ==
'y') || (LastChar ==
'Y'))
2311 ShowMessage(
"Railway not ready for operation so unable to load as a .rly file. Loading as a new railway under development");
2318 Screen->Cursor = TCursor(-2);
2351 ShowMessage(
"File open failed prior to load");
2352 Screen->Cursor = TCursor(-2);
2355 ShowMessage(
"File integrity check failed - unable to load");
2370 Screen->Cursor = TCursor(-11);
2372 if(!(VecFile.fail()))
2399 ShowMessage(
"File open failed prior to save");
2400 Screen->Cursor = TCursor(-2);
2405 catch(
const Exception &e)
2421 catch(
const Exception &e)
2437 ShowMessage(
"Failed to find folder " +
IMAGE_DIR_NAME +
" in the folder where 'railway.exe' resides. Image can't be saved");
2441 Screen->Cursor = TCursor(-11);
2444 AnsiString ImageFileName = TDateTime::CurrentDateTime().FormatString(
"dd-mm-yyyy hh.nn.ss");
2448 AnsiString ShortName =
"";
2449 for(
int x = ImageFileName.Length(); x > 0; x--)
2451 if(ImageFileName[x] ==
'\\')
2453 ShortName = ImageFileName.SubString(x + 1, ImageFileName.Length() - x - 4);
2457 ShowMessage(
"A bitmap file named " + ShortName +
" will be created in the Images folder");
2458 Graphics::TBitmap *RailwayImage =
new Graphics::TBitmap;
2459 RailwayImage->PixelFormat = pf8bit;
2465 RailwayImage->Width = HPosMax - HPosMin;
2466 RailwayImage->Height = VPosMax - VPosMin;
2474 int NewWidth = (TextPtr->HPos - HPosMin) + (abs(TextPtr->Font->Height) * TextPtr->TextString.Length() * 0.7);
2475 int NewHeight = (TextPtr->VPos - VPosMin) + (abs(TextPtr->Font->Height) * 1.5);
2476 if(NewWidth > RailwayImage->Width)
2478 RailwayImage->Width = NewWidth;
2480 if(NewHeight > RailwayImage->Height)
2482 RailwayImage->Height = NewHeight;
2487 RailwayImage->Canvas->Brush->Color =
clB5G5R5;
2488 TRect Rect(0, 0, RailwayImage->Width, RailwayImage->Height);
2489 RailwayImage->Canvas->FillRect(Rect);
2497 RailwayImage->SaveToFile(ImageFileName);
2498 delete RailwayImage;
2501 Screen->Cursor = TCursor(-2);
2504 catch(
const Exception &e)
2506 if(e.Message.Pos(
"torage") > 0)
2508 Screen->Cursor = TCursor(-2);
2509 UnicodeString MessageStr =
"Insufficient memory available to store this image";
2510 Application->MessageBox(MessageStr.c_str(), L
"", MB_OK | MB_ICONWARNING);
2529 ShowMessage(
"Failed to find folder " +
IMAGE_DIR_NAME +
" in the folder where 'railway.exe' resides. Image can't be saved");
2533 Screen->Cursor = TCursor(-11);
2536 AnsiString ImageFileName = TDateTime::CurrentDateTime().FormatString(
"dd-mm-yyyy hh.nn.ss");
2540 AnsiString ShortName =
"";
2541 for(
int x = ImageFileName.Length(); x > 0; x--)
2543 if(ImageFileName[x] ==
'\\')
2545 ShortName = ImageFileName.SubString(x + 1, ImageFileName.Length() - x - 4);
2549 ShowMessage(
"A bitmap file named " + ShortName +
" will be created in the Images folder");
2550 Graphics::TBitmap *RailwayImage =
new Graphics::TBitmap;
2551 RailwayImage->PixelFormat = pf8bit;
2556 RailwayImage->Width = HPosMax - HPosMin;
2557 RailwayImage->Height = VPosMax - VPosMin;
2565 int NewWidth = (TextPtr->HPos - HPosMin) + (abs(TextPtr->Font->Height) * TextPtr->TextString.Length() * 0.7);
2566 int NewHeight = (TextPtr->VPos - VPosMin) + (abs(TextPtr->Font->Height) * 1.5);
2567 if(NewWidth > RailwayImage->Width)
2569 RailwayImage->Width = NewWidth;
2571 if(NewHeight > RailwayImage->Height)
2573 RailwayImage->Height = NewHeight;
2578 RailwayImage->Canvas->Brush->Color =
clB5G5R5;
2579 TRect Rect(0, 0, RailwayImage->Width, RailwayImage->Height);
2580 RailwayImage->Canvas->FillRect(Rect);
2583 for(
int x = 0; x < ((RailwayImage->Width) / 16); x++)
2585 for(
int y = 0; y < ((RailwayImage->Height) / 16); y++)
2595 RailwayImage->SaveToFile(ImageFileName);
2596 delete RailwayImage;
2599 Screen->Cursor = TCursor(-2);
2602 catch(
const Exception &e)
2604 if(e.Message.Pos(
"torage") > 0)
2606 Screen->Cursor = TCursor(-2);
2607 UnicodeString MessageStr =
"Insufficient memory available to store this image";
2608 Application->MessageBox(MessageStr.c_str(), L
"", MB_OK | MB_ICONWARNING);
2626 ShowMessage(
"Failed to find folder " +
IMAGE_DIR_NAME +
" in the folder where 'railway.exe' resides. Image can't be saved");
2630 Screen->Cursor = TCursor(-11);
2633 AnsiString ImageFileName = TDateTime::CurrentDateTime().FormatString(
"dd-mm-yyyy hh.nn.ss");
2637 AnsiString ShortName =
"";
2638 for(
int x = ImageFileName.Length(); x > 0; x--)
2640 if(ImageFileName[x] ==
'\\')
2642 ShortName = ImageFileName.SubString(x + 1, ImageFileName.Length() - x - 4);
2646 ShowMessage(
"A bitmap file named " + ShortName +
" will be created in the Images folder");
2647 Graphics::TBitmap *RailwayImage =
new Graphics::TBitmap;
2648 RailwayImage->PixelFormat = pf8bit;
2653 RailwayImage->Width = HPosMax - HPosMin;
2654 RailwayImage->Height = VPosMax - VPosMin;
2662 int NewWidth = (TextPtr->HPos - HPosMin) + (abs(TextPtr->Font->Height) * TextPtr->TextString.Length() * 0.7);
2663 int NewHeight = (TextPtr->VPos - VPosMin) + (abs(TextPtr->Font->Height) * 1.5);
2664 if(NewWidth > RailwayImage->Width)
2666 RailwayImage->Width = NewWidth;
2668 if(NewHeight > RailwayImage->Height)
2670 RailwayImage->Height = NewHeight;
2675 RailwayImage->Canvas->Brush->Color =
clB5G5R5;
2676 TRect Rect(0, 0, RailwayImage->Width, RailwayImage->Height);
2677 RailwayImage->Canvas->FillRect(Rect);
2685 RailwayImage->SaveToFile(ImageFileName);
2686 delete RailwayImage;
2689 Screen->Cursor = TCursor(-2);
2692 catch(
const Exception &e)
2694 if(e.Message.Pos(
"torage") > 0)
2696 Screen->Cursor = TCursor(-2);
2697 UnicodeString MessageStr =
"Insufficient memory available to store this image";
2698 Application->MessageBox(MessageStr.c_str(), L
"", MB_OK | MB_ICONWARNING);
2716 ShowMessage(
"Failed to find folder " +
IMAGE_DIR_NAME +
" in the folder where 'railway.exe' resides. Image can't be saved");
2720 Screen->Cursor = TCursor(-11);
2725 TimetableTimeStr = TimetableTimeStr.SubString(1, 2) +
'.' + TimetableTimeStr.SubString(4, 2) +
'.' + TimetableTimeStr.SubString(7, 2);
2726 AnsiString ImageFileName = TDateTime::CurrentDateTime().FormatString(
"dd-mm-yyyy hh.nn.ss");
2731 AnsiString ShortName =
"";
2732 for(
int x = ImageFileName.Length(); x > 0; x--)
2734 if(ImageFileName[x] ==
'\\')
2736 ShortName = ImageFileName.SubString(x + 1, ImageFileName.Length() - x - 4);
2740 ShowMessage(
"A bitmap file named " + ShortName +
" will be created in the Images folder");
2741 Graphics::TBitmap *RailwayImage =
new Graphics::TBitmap;
2742 RailwayImage->PixelFormat = pf8bit;
2747 RailwayImage->Width = HPosMax - HPosMin;
2748 RailwayImage->Height = VPosMax - VPosMin;
2756 int NewWidth = (TextPtr->HPos - HPosMin) + (abs(TextPtr->Font->Height) * TextPtr->TextString.Length() * 0.7);
2757 int NewHeight = (TextPtr->VPos - VPosMin) + (abs(TextPtr->Font->Height) * 1.5);
2758 if(NewWidth > RailwayImage->Width)
2760 RailwayImage->Width = NewWidth;
2762 if(NewHeight > RailwayImage->Height)
2764 RailwayImage->Height = NewHeight;
2769 RailwayImage->Canvas->Brush->Color =
clB5G5R5;
2770 TRect Rect(0, 0, RailwayImage->Width, RailwayImage->Height);
2771 RailwayImage->Canvas->FillRect(Rect);
2786 bool BreakFlag =
false;
2812 RailwayImage->SaveToFile(ImageFileName);
2813 delete RailwayImage;
2816 Screen->Cursor = TCursor(-2);
2819 catch(
const Exception &e)
2821 if(e.Message.Pos(
"torage") > 0)
2823 Screen->Cursor = TCursor(-2);
2824 UnicodeString MessageStr =
"Insufficient memory available to store this image";
2825 Application->MessageBox(MessageStr.c_str(), L
"", MB_OK | MB_ICONWARNING);
2853 Screen->Cursor = TCursor(-11);
2855 if(!(VecFile.fail()))
2882 ShowMessage(
"Railway failed to save - can't open file");
2883 Screen->Cursor = TCursor(-2);
2887 catch(
const Exception &e)
2901 catch(
const Exception &e)
2921 catch(
const Exception &e)
2936 ShowMessage(
"Failed to find folder " +
FORMATTEDTT_DIR_NAME +
" in the folder where 'railway.exe' resides. Timetable can't be exported");
2944 Screen->Cursor = TCursor(-2);
2947 catch(
const Exception &e)
3006 AZOrderButton->Hint = AnsiString(
"Arrange services in alphabetical order Toggle with Shift+ Z");
3023 ActiveTrackElementNameMapEntry.first =
Track->
TrackVector.at(x).ActiveTrackElementName;
3024 ActiveTrackElementNameMapEntry.second = 0;
3074 catch(
const Exception &e)
3117 if(TTBLFile.is_open())
3121 while(!TTBLFile.eof())
3124 if((c < 32) && (c != 13) && (c != 10) && (c !=
'\0'))
3126 ShowMessage(
"Timetable file is empty or contains non-ascii characters, codes must be between 20 and 127, or CR or LF");
3136 ShowMessage(
"Failed to open timetable file, make sure it's not open in another application");
3143 if(TTBLFile.is_open())
3152 AZOrderButton->Hint = AnsiString(
"Arrange services in alphabetical order Toggle with Shift+ Z");
3165 char *TimetableEntryString =
new char[10000];
3168 TTBLFile.getline(TimetableEntryString, 10000,
'\0');
3169 if(TTBLFile.eof() && (TimetableEntryString[0] ==
'\0'))
3174 AnsiString OneLine(TimetableEntryString);
3178 delete TimetableEntryString;
3183 ShowMessage(
"Failed to open timetable file, make sure it's not open in another application");
3219 ActiveTrackElementNameMapEntry.first =
Track->
TrackVector.at(x).ActiveTrackElementName;
3220 ActiveTrackElementNameMapEntry.second = 0;
3245 catch(
const Exception &e)
3263 InfoPanel->Caption =
"Timetable mode: editor hidden";
3269 ShowHideTTButton->Hint =
"Hide the timetable editor to see the railway Shift H";
3274 catch(
const Exception &e)
3313 catch(
const Exception &e)
3352 catch(
const Exception &e)
3372 catch(
const Exception &e)
3385 bool ValidFlag =
true;
3404 TDateTime DummyTime;
3422 ShowMessage(
"One or more times excessive, not permitted to exceed 95 hours");
3426 AnsiString MinsStr = AnsiString(Mins), HrsStr = AnsiString(Hrs);
3428 MinsStr =
"0" + MinsStr;
3430 HrsStr =
"0" + HrsStr;
3433 NewString += HrsStr +
':' + MinsStr;
3450 catch(
const Exception &e)
3463 bool ValidFlag =
true;
3482 TDateTime DummyTime;
3500 ShowMessage(
"One or more times are now before 00:00, this is not permitted");
3504 AnsiString MinsStr = AnsiString(Mins), HrsStr = AnsiString(Hrs);
3506 MinsStr =
"0" + MinsStr;
3508 HrsStr =
"0" + HrsStr;
3511 NewString += HrsStr +
':' + MinsStr;
3527 catch(
const Exception &e)
3565 catch(
const Exception &e)
3611 if(OldVectorPos == 0)
3639 catch(
const Exception &e)
3698 catch(
const Exception &e)
3716 UnicodeString MessageStr =
"Are you sure this entry should be deleted?";
3717 int button = Application->MessageBox(MessageStr.c_str(), L
"Please confirm", MB_YESNO);
3749 if(OldVectorPos == 0)
3777 catch(
const Exception &e)
3798 AnsiString TempStr =
"";
3799 bool ActiveLine =
false;
3824 while(TempStr[TempStr.Length()] ==
',')
3826 TempStr = TempStr.SubString(1, TempStr.Length() - 1);
3855 (*TTCurrentEntryPtr) = TempStr;
3925 catch(
const Exception &e)
3940 ShowMessage(
"Timetable is empty, can't save an empty timetable");
3944 std::ofstream TTBLFile;
3974 if(TTBLFile.is_open())
3978 TTBLFile << (*TEVPtr).c_str() <<
'\0';
3985 ShowMessage(
CreateEditTTFileName +
" failed to open, ensure not already open in another application");
3991 catch(
const Exception &e)
4006 ShowMessage(
"Timetable is empty, can't save an empty timetable");
4010 std::ofstream TTBLFile;
4014 for(
int x =
SaveTTDialog->FileName.Length(); x > 0; x--)
4032 if(TTBLFile.is_open())
4036 TTBLFile << (*TEVPtr).c_str() <<
'\0';
4043 ShowMessage(
CreateEditTTFileName +
" failed to open, ensure not already open in another application");
4049 catch(
const Exception &e)
4063 bool EndOfFile =
false;
4064 bool FinalCallFalse =
false;
4065 bool GiveMessagesTrue =
true;
4066 bool CheckLocationsExistInRailway =
false;
4068 CheckLocationsExistInRailway =
true;
4074 "The basic syntax seems OK but this check is very limited. Other aspects can only be checked by validating the whole timetable with the appropriate railway (.rly) loaded");
4080 catch(
const Exception &e)
4108 bool CheckLocationsExistInRailwayTrue =
true;
4111 Screen->Cursor = TCursor(-11);
4113 if(TTBLFile.is_open())
4117 ShowMessage(
"Timetable integrity OK");
4124 ShowMessage(
"Failed to open timetable file, make sure it's not open in another application");
4126 Screen->Cursor = TCursor(-2);
4136 catch(
const Exception &e)
4160 AnsiString TempStr = *
TEVPtr;
4198 catch(
const Exception &e)
4222 AnsiString TempStr = *
TEVPtr;
4260 catch(
const Exception &e)
4297 catch(
const Exception &e)
4312 UnicodeString MessageStr =
"All changes to the timetable will be lost - proceed?";
4313 int button = Application->MessageBox(MessageStr.c_str(), L
"Please confirm", MB_YESNO);
4324 if(TTBLFile.is_open())
4341 char *TimetableEntryString =
new char[10000];
4344 TTBLFile.getline(TimetableEntryString, 10000,
'\0');
4345 if(TTBLFile.eof() && (TimetableEntryString[0] ==
'\0'))
4350 AnsiString OneLine(TimetableEntryString);
4354 delete TimetableEntryString;
4359 ShowMessage(
"Failed to open timetable file, make sure it's not open in another application");
4380 catch(
const Exception &e)
4395 ShowMessage(
"Failed to find folder " +
FORMATTEDTT_DIR_NAME +
" in the folder where 'railway.exe' resides. Timetable can't be exported");
4414 Screen->Cursor = TCursor(-2);
4419 catch(
const Exception &e)
4452 catch(
const Exception &e)
4467 UnicodeString MessageStr =
"The timetable has changed.\n\nAre you sure you want to exit without saving it?";
4468 int button = Application->MessageBox(MessageStr.c_str(), L
"Please confirm", MB_YESNO);
4484 catch(
const Exception &e)
4512 catch(
const Exception &e)
4537 catch(
const Exception &e)
4555 catch(
const Exception &e)
4578 catch(
const Exception &e)
4587 TShiftState Shift,
int X,
int Y)
4631 catch(
const Exception &e)
4660 if((TopPos + (Y / 13)) >=
OAListBox->Items->Count)
4668 std::advance(OACurrentEntryPtr, ((Y / 13) + TopPos));
4672 int TrackVectorPosition;
4673 int TrainIDorTVPos = OACurrentEntryPtr->second.second;
4674 if(TrainIDorTVPos >= 0)
4690 TrackVectorPosition = -(TrainIDorTVPos + 1);
4705 TPoint MainScreenPoint(ScreenPosH + 8, ScreenPosV + 8);
4706 TPoint CursPos =
MainScreen->ClientToScreen(MainScreenPoint);
4707 Mouse->CursorPos = CursPos;
4710 catch(
const Exception &e)
4722 PreStartTime, ActiveSegment, PostEnd} Segment;
4735 Segment = PreStartTime;
4738 if(Segment == PreStartTime)
4745 Segment = ActiveSegment;
4756 AnsiString CurrentStr = *
TEVPtr;
4757 if(CurrentStr !=
"")
4759 CurrentStr = CurrentStr.SubString(1, 10);
4760 for(
int x = 1; x < CurrentStr.Length(); x++)
4762 if((CurrentStr[x] < 32) || (CurrentStr[1] > 126))
4764 CurrentStr = CurrentStr.SubString(1, (x - 1));
4773 if(Segment == ActiveSegment)
4788 AnsiString Entry = *
TEVPtr;
4793 int SCPos = Entry.Pos(
';');
4794 int CPos = Entry.Pos(
',');
4801 if((CPos == 0) && (SCPos == 0))
4803 Entry = Entry.SubString(1, 12);
4805 else if((CPos > 0) && (SCPos > 0) && (CPos < SCPos))
4807 Entry = Entry.SubString(1, CPos - 1);
4809 else if((CPos > 0) && (SCPos > 0) && (CPos > SCPos))
4811 Entry = Entry.SubString(1, SCPos - 1);
4813 else if((CPos > 0) && (SCPos == 0))
4815 Entry = Entry.SubString(1, CPos - 1);
4819 Entry = Entry.SubString(1, SCPos - 1);
4832 if(Segment == PostEnd)
4840 AnsiString CurrentStr = *
TEVPtr;
4841 if(CurrentStr !=
"")
4843 CurrentStr = CurrentStr.SubString(1, 10);
4844 for(
int x = 1; x < CurrentStr.Length(); x++)
4846 if((CurrentStr[x] < 32) || (CurrentStr[1] > 126))
4848 CurrentStr = CurrentStr.SubString(1, (x - 1));
4879 UnicodeString MessageStr =
4880 "If you wish to preserve the original order don't make any changes whilst in alphabetical order.\n\nIn that case use alphabetical order to find the service required, click it to display it, then revert to the original order where the same service will be displayed and can be changed.";
4881 Application->MessageBox(MessageStr.c_str(), L
"Please Note:", MB_OK | MB_ICONWARNING);
4894 std::sort(SortStart, SortEnd);
4896 bool CurrentEntryChanged =
false;
4902 CurrentEntryChanged =
true;
4905 if(!CurrentEntryChanged)
4910 AZOrderButton->Hint = AnsiString(
"Arrange services in original order Toggle with Shift+ Z");
4916 UnicodeString MessageStr =
4917 "Reverting to the original order will discard any changes made whilst in alphabetical order.\n\nTo preserve the changes click 'No', then save the timetable or use 'save as' if you wish to keep the original timetable.\n\nDo you wish to proceed?";
4918 int button = Application->MessageBox(MessageStr.c_str(), L
"Warning!", MB_YESNO | MB_ICONWARNING);
4932 bool CurrentEntryChanged =
false;
4938 CurrentEntryChanged =
true;
4941 if(!CurrentEntryChanged)
4946 AZOrderButton->Hint = AnsiString(
"Arrange services in alphabetical order Toggle with Shift+ Z");
4955 catch(
const Exception &e)
4966 AnsiString OutStr =
"";
4969 while(x < ConvStr.Length())
4971 if((ConvStr[x] ==
'\r') && (ConvStr[x + 1] ==
'\n'))
4979 OutStr += ConvStr[x];
4983 if(x == ConvStr.Length())
4984 OutStr += ConvStr[x];
4989 while(OutStr[OutStr.Length()] ==
',')
4991 OutStr = OutStr.SubString(1, OutStr.Length() - 1);
5061 InfoPanel->Caption =
"Select option or change entry";
5075 bool ValidFlag =
true;
5076 for(
int x = 1; x <= AnsiAddSubText.Length(); x++)
5078 if((AnsiAddSubText[x] >
'9') || (AnsiAddSubText[x] <
'0'))
5086 if(AnsiAddSubText.ToInt() != 0)
5158 bool ServiceEntry =
true;
5163 bool ServiceEntry =
false;
5175 InfoPanel->Caption =
"Add or change entry then save it, or cancel";
5185 AnsiString((
short)ServiceEntry));
5192 int CommaPos = Data.Pos(
',');
5193 if((CommaPos == 0) && (Data !=
""))
5195 CommaPos = Data.Length() + 1;
5198 if(Data.Length() <= CommaPos)
5200 Data = Data.SubString(CommaPos + 1, Data.Length() - CommaPos);
5237 if(CurrentStr !=
"")
5239 for(
int x = 1; x < CurrentStr.Length(); x++)
5241 if((CurrentStr[x] < 32) || (CurrentStr[1] > 126))
5243 CurrentStr = CurrentStr.SubString(1, (x - 1));
5268 TDateTime DummyTime;
5269 bool TimesPresent =
false;
5277 TimesPresent =
true;
5284 return TimesPresent;
5298 UnicodeString MessageStr =
5299 "Note that leaving the track unlinked will cause preferred directions to be lost on reloading. Prevent by linking the track then resaving. Do you still wish to exit?";
5300 int button = Application->MessageBox(MessageStr.c_str(), L
"Please confirm", MB_YESNO);
5309 UnicodeString MessageStr =
"The railway has changed, exit without saving?";
5310 int button = Application->MessageBox(MessageStr.c_str(), L
"Please confirm", MB_YESNO);
5322 Application->Terminate();
5324 catch(
const Exception &e)
5347 catch(
const Exception &e)
5370 catch(
const Exception &e)
5393 catch(
const Exception &e)
5452 catch(
const Exception &e)
5470 catch(
const Exception &e)
5489 catch(
const Exception &e)
5524 catch(
const Exception &e)
5535 TrainController->
LogEvent(
"MainScreenMouseDown2," + AnsiString(Button) +
"," + AnsiString(X) +
"," + AnsiString(Y));
5537 "," + AnsiString(Y));
5548 int NoOffsetX, NoOffsetY;
5550 if(Button == mbRight)
5554 AnsiString Text =
"";
5561 Screen->Cursor = TCursor(-22);
5612 bool TrackEraseSuccessfulFlag;
5613 int ErasedTrackVectorPosition;
5614 Screen->Cursor = TCursor(-11);
5616 if(TrackEraseSuccessfulFlag)
5618 if(ErasedTrackVectorPosition > -1)
5649 Screen->Cursor = TCursor(-2);
5657 bool LeadingPointsAtLastElement =
false;
5672 if(!LeadingPointsAtLastElement)
5677 InfoPanel->Caption =
"DISTANCE/SPEED SETTING: Continue or set values (overall length), or right click to cancel/truncate";
5692 InfoPanel->Caption =
"DISTANCE/SPEED SETTING: Can't end on leading points, continue or truncate";
5769 if((TrainID01 > -1) && (TrainID23 > -1))
5819 AnsiString LocName =
"";
5824 if((LocName ==
"") && (Train.
MidElement > -1))
5938 Screen->Cursor = TCursor(-11);
5949 Screen->Cursor = TCursor(-2);
6016 Screen->Cursor = TCursor(-11);
6018 bool TrackLinkingRequiredFlag;
6020 TSpeedButton *TempSpeedButton = 0;
6028 bool InternalChecks =
true;
6034 if(TrackLinkingRequiredFlag)
6063 Screen->Cursor = TCursor(-2);
6077 NewGI.
Width = UGMIt->second->Width;
6078 NewGI.
Height = UGMIt->second->Height;
6103 AnsiString NameString;
6113 unsigned int ValidPosition;
6124 ValidElement = InactiveTrackElement1;
6125 ValidPosition = InactivePair.first;
6130 ValidElement = InactiveTrackElement2;
6131 ValidPosition = InactivePair.second;
6142 InfoPanel->Caption =
"NAMING LOCATIONS: Enter name, 'Carriage Return' to accept, 'Escape' to quit";
6173 bool FinishElement =
false, LeadingPointsAtLastElement =
false;
6174 Screen->Cursor = TCursor(-11);
6188 InfoPanel->Caption =
"DISTANCE/SPEED SETTING: Set values (overall length), or right click to cancel/truncate";
6198 Screen->Cursor = TCursor(-2);
6204 if(!LeadingPointsAtLastElement)
6209 InfoPanel->Caption =
"DISTANCE/SPEED SETTING: Continue or set values (overall length), or right click to cancel/truncate";
6226 InfoPanel->Caption =
"DISTANCE/SPEED SETTING: Can't end on leading points, need to continue or truncate";
6241 Screen->Cursor = TCursor(-2);
6246 Screen->Cursor = TCursor(-2);
6263 InfoPanel->Caption =
"CONNECTING GAPS: Connecting element selected";
6275 ShowMessage(
"All gaps set");
6303 int TrueX = 0, TrueY = 0;
6304 AnsiString ExistingText =
"";
6306 TFont *ExistingTextFont =
new TFont;
6307 int ExistingTextHPos = 0, ExistingTextVPos = 0;
6313 if((TrueX >= TextPtr->HPos) && (TrueX < (TextPtr->HPos + abs(TextPtr->Font->Height))) && (TrueY >= TextPtr->VPos) && (TrueY <
6314 (TextPtr->VPos + abs(TextPtr->Font->Height))))
6316 ExistingText = TextPtr->TextString;
6317 ExistingTextFont->Assign(TextPtr->Font);
6318 ExistingTextHPos = TextPtr->HPos;
6319 ExistingTextVPos = TextPtr->VPos;
6331 TextBox->Font->Assign(ExistingTextFont);
6333 Text_X = ExistingTextHPos;
6334 Text_Y = ExistingTextVPos;
6349 TextBox->Text =
"New Text: CR=end, ESC=quit";
6352 delete ExistingTextFont;
6444 Screen->Cursor = TCursor(-11);
6453 ShowMessage(
"Preferred direction added");
6457 Screen->Cursor = TCursor(-2);
6476 Screen->Cursor = TCursor(-2);
6480 Screen->Cursor = TCursor(-2);
6577 AnsiString(PDE.
VLoc));
6590 bool PointsChanged =
false;
6591 IDInt ReqPosRouteID(-1);
6593 bool CallonTrue =
true;
6594 bool ConsecSignalsRouteFalse =
false;
6603 CallonTrue, ReqPosRouteID, PointsChanged))
6645 float TempSpeedVal = 1;
6713 int DivergingPosition = TrackElement.
Conn[3];
6715 DivergingPosition)))
6790 InfoPanel->Caption =
"PRE-START: Select next route location";
6792 InfoPanel->Caption =
"OPERATING: Select next route location";
6804 bool CallonFalse =
false;
6811 InfoPanel->Caption =
"PRE-START: Select next route location";
6813 InfoPanel->Caption =
"OPERATING: Select next route location";
6831 Screen->Cursor = TCursor(-11);
6833 bool PointsChanged =
false;
6843 float TempSpeedVal = 1;
6848 else if(PointsChanged)
6859 Screen->Cursor = TCursor(-2);
6867 bool CallonFalse =
false;
6873 float TempSpeedVal = 1;
6878 else if(PointsChanged)
6892 Screen->Cursor = TCursor(-2);
6901 catch(
const Exception &e)
6915 TrainController->
LogEvent(
"MainScreenMouseDown3," + AnsiString(Button) +
"," + AnsiString(X) +
"," + AnsiString(Y));
6917 "," + AnsiString(Y));
6918 if(Button != mbLeft)
6924 Screen->Cursor = TCursor(-22);
6930 int HRounding, VRounding;
6981 else if(TempLevel2OperMode ==
Operating)
6984 OperateButton->Glyph->LoadFromResourceName(0,
"PauseGraphic");
6988 else if(TempLevel2OperMode ==
Paused)
6991 OperateButton->Glyph->LoadFromResourceName(0,
"RunGraphic");
6997 else if(TempLevel2OperMode ==
PreStart)
7000 OperateButton->Glyph->LoadFromResourceName(0,
"RunGraphic");
7011 catch(
const Exception &e)
7101 if(CurrentHLoc >= StartHLoc)
7105 if(CurrentVLoc >= StartVLoc)
7117 TRect TempRect(StartHLoc, StartVLoc, CurrentHLoc, CurrentVLoc);
7131 if(CurrentHLoc >= StartHLoc)
7135 if(CurrentVLoc >= StartVLoc)
7147 TRect TempRect(StartHLoc, StartVLoc, CurrentHLoc, CurrentVLoc);
7206 catch(
const Exception &e)
7242 TrainController->
LogEvent(
"MainScreenMouseUp," + AnsiString(Button) +
"," + AnsiString(X) +
"," + AnsiString(Y));
7245 Screen->Cursor = TCursor(-2);
7249 Screen->Cursor = TCursor(-11);
7254 if(EndHLoc >= StartHLoc)
7258 if(EndVLoc >= StartVLoc)
7262 if(StartHLoc >= EndHLoc)
7272 if(StartVLoc >= EndVLoc)
7298 Screen->Cursor = TCursor(-2);
7364 if(IATVecPair.second != IATVecPair.first)
7382 if((TextPtr->HPos >= LowSelectHPos) && (TextPtr->HPos < HighSelectHPos) && (TextPtr->VPos >= LowSelectVPos) && (TextPtr->VPos <
7390 bool SelectVectorNamedElement =
false;
7391 AnsiString SelectTextString;
7396 SelectVectorNamedElement =
true;
7400 if(SelectVectorNamedElement)
7402 SelectTextString =
"##**" + TextPtr->TextString;
7406 SelectTextString = TextPtr->TextString;
7408 TTextItem TextItem(TextPtr->HPos, TextPtr->VPos, SelectTextString, TextPtr->Font);
7417 for(TTrack::TUserGraphicVector::iterator UserGraphicPtr =
Track->
UserGraphicVector.begin(); UserGraphicPtr < Track->UserGraphicVector.end();
7420 if((UserGraphicPtr->HPos >= LowSelectHPos) && ((UserGraphicPtr->HPos + UserGraphicPtr->Width) < HighSelectHPos) &&
7421 (UserGraphicPtr->VPos >= LowSelectVPos) && ((UserGraphicPtr->VPos + UserGraphicPtr->Height) < HighSelectVPos))
7434 Screen->Cursor = TCursor(-2);
7440 Screen->Cursor = TCursor(-11);
7446 if(EndHLoc >= StartHLoc)
7450 if(EndVLoc >= StartVLoc)
7454 if(StartHLoc >= EndHLoc)
7464 if(StartVLoc >= EndVLoc)
7489 Screen->Cursor = TCursor(-2);
7518 Screen->Cursor = TCursor(-2);
7544 catch(
const Exception &e)
7577 throw Exception(
"Warning - Utilities->CallLog contains more than 50 items");
7604 catch(
const Exception &e)
7684 if(
WholeRailwayMoving && (GetAsyncKeyState(VK_LBUTTON) >= 0) && (GetAsyncKeyState(VK_RBUTTON) >= 0))
7687 Screen->Cursor = TCursor(-2);
7714 bool TrainPresent =
false;
7728 TDateTime TempExcessLCDownTime;
7733 if(TempExcessLCDownTime > TDateTime(0))
7761 bool ElementRemovedFlag =
false;
7772 ElementRemovedFlag =
true;
7787 bool WH1 = (Mouse->CursorPos.x >= ClientOrigin.x +
OutputLog1->Left) && (Mouse->CursorPos.x < (ClientOrigin.x +
OutputLog1->Width +
OutputLog1->Left))
7790 bool WH2 = (Mouse->CursorPos.x >= ClientOrigin.x +
OutputLog2->Left) && (Mouse->CursorPos.x < (ClientOrigin.x +
OutputLog2->Width +
OutputLog2->Left))
7793 bool WH3 = (Mouse->CursorPos.x >= ClientOrigin.x +
OutputLog3->Left) && (Mouse->CursorPos.x < (ClientOrigin.x +
OutputLog3->Width +
OutputLog3->Left))
7796 bool WH4 = (Mouse->CursorPos.x >= ClientOrigin.x +
OutputLog4->Left) && (Mouse->CursorPos.x < (ClientOrigin.x +
OutputLog4->Width +
OutputLog4->Left))
7799 bool WH5 = (Mouse->CursorPos.x >= ClientOrigin.x +
OutputLog5->Left) && (Mouse->CursorPos.x < (ClientOrigin.x +
OutputLog5->Width +
OutputLog5->Left))
7802 bool WH6 = (Mouse->CursorPos.x >= ClientOrigin.x +
OutputLog6->Left) && (Mouse->CursorPos.x < (ClientOrigin.x +
OutputLog6->Width +
OutputLog6->Left))
7805 bool WH7 = (Mouse->CursorPos.x >= ClientOrigin.x +
OutputLog7->Left) && (Mouse->CursorPos.x < (ClientOrigin.x +
OutputLog7->Width +
OutputLog7->Left))
7808 bool WH8 = (Mouse->CursorPos.x >= ClientOrigin.x +
OutputLog8->Left) && (Mouse->CursorPos.x < (ClientOrigin.x +
OutputLog8->Width +
OutputLog8->Left))
7811 bool WH9 = (Mouse->CursorPos.x >= ClientOrigin.x +
OutputLog9->Left) && (Mouse->CursorPos.x < (ClientOrigin.x +
OutputLog9->Width +
OutputLog9->Left))
7814 bool WH10 = (Mouse->CursorPos.x >= ClientOrigin.x +
OutputLog10->Left) &&
7818 if(WH1 || WH2 || WH3 || WH4 || WH5 || WH6 || WH7 || WH8 || WH9 || WH10)
7839 AnsiString Type[15] =
7840 {
"Simple",
"Crossover",
"Points",
"Buffers",
"Bridge",
"SignalPost",
"Continuation",
"Platform",
"GapJump",
"FootCrossing",
"Unused",
"Concourse",
7841 "Parapet",
"NamedNonStationLocation",
"Erase"};
7843 int ScreenX = Mouse->CursorPos.x -
MainScreen->ClientOrigin.x;
7844 int ScreenY = Mouse->CursorPos.y -
MainScreen->ClientOrigin.y;
7846 AnsiString MouseStr =
"Posx: " + AnsiString(ScreenX) +
"; Posy: " + AnsiString(ScreenY);
7851 DevelopmentPanel->Caption = MouseStr +
"; TVPos: " + AnsiString(Position) +
"; H: " + AnsiString(HLoc) +
"; V: " + AnsiString(VLoc) +
7852 "; SpTg: " + AnsiString(TrackElement.
SpeedTag) +
"; Type: " + Type[TrackElement.
TrackType] +
"; Att: " + AnsiString(TrackElement.
Attribute)
7870 if((GetKeyState(VK_LBUTTON) >= 0) && (GetKeyState(VK_RBUTTON) >= 0) && (
TTCurrentEntryPtr > 0))
8001 Screen->Cursor = TCursor(-11);
8157 int RouteStartVecPos;
8167 if(FoundFlag && (RouteStartVecPos > -1))
8183 catch(
const Exception &e)
8201 InfoPanel->Caption =
"CALLING ON: Select signal for call on";
8215 catch(
const Exception &e)
8229 Screen->Cursor = TCursor(-11);
8271 Screen->Cursor = TCursor(-2);
8274 catch(
const Exception &e)
8288 Screen->Cursor = TCursor(-11);
8330 Screen->Cursor = TCursor(-2);
8333 catch(
const Exception &e)
8347 Screen->Cursor = TCursor(-11);
8390 Screen->Cursor = TCursor(-2);
8393 catch(
const Exception &e)
8407 Screen->Cursor = TCursor(-11);
8449 Screen->Cursor = TCursor(-2);
8452 catch(
const Exception &e)
8466 Screen->Cursor = TCursor(-11);
8503 OperateButton->Glyph->LoadFromResourceName(0,
"PauseGraphic");
8510 OperateButton->Glyph->LoadFromResourceName(0,
"RunGraphic");
8519 OperateButton->Glyph->LoadFromResourceName(0,
"RunGraphic");
8546 if((LeftExcess > 0) && (RightExcess > 0))
8548 else if((LeftExcess > 0) && (RightExcess <= 0))
8551 else if((LeftExcess <= 0) && (RightExcess > 0))
8559 if((TopExcess > 0) && (BotExcess > 0))
8561 else if((TopExcess > 0) && (BotExcess <= 0))
8564 else if((TopExcess <= 0) && (BotExcess > 0))
8574 ZoomButton->Glyph->LoadFromResourceName(0,
"ZoomIn");
8576 Screen->Cursor = TCursor(-2);
8580 catch(
const Exception &e)
8594 Screen->Cursor = TCursor(-11);
8617 Screen->Cursor = TCursor(-2);
8621 catch(
const Exception &e)
8649 catch(
const Exception &e)
8665 catch(
const Exception &e)
8692 catch(
const Exception &e)
8715 TRect NewSelectRect(TLHCH, TLHCV, BRHCH, BRHCV);
8748 catch(
const Exception &e)
8767 catch(
const Exception &e)
8786 catch(
const Exception &e)
8834 int MidVPosAfterFlip = ((VerSum * 16) + 15) - MidVPosBeforeFlip;
8842 catch(
const Exception &e)
8890 int MidHPosAfterMirror = ((HorSum * 16) + 15) - MidHPosBeforeMirror;
8892 if(LeftPosAfterMirror < (
SelectRect.left * 16))
8902 catch(
const Exception &e)
8955 int MidVPosAfterFlip = ((VerSum * 16) + 15) - MidVPosBeforeFlip;
8967 int MidHPosAfterMirror = ((HorSum * 16) + 15) - MidHPosBeforeMirror;
8969 if(LeftPosAfterMirror < (
SelectRect.left * 16))
8981 catch(
const Exception &e)
8994 Screen->Cursor = TCursor(-11);
9011 int button = Application->MessageBox
9012 (L
"Original selection adjusted to make it square. 'OK' to keep this selection or 'Cancel' to make a new selection",
9013 L
"Left click and hold here to move this message box", MB_OKCANCEL);
9014 if(button == IDCANCEL)
9022 Screen->Cursor = TCursor(-2);
9059 if(IATVecPair.second != IATVecPair.first)
9077 if((TextPtr->HPos >= LowSelectHPos) && (TextPtr->HPos < HighSelectHPos) && (TextPtr->VPos >= LowSelectVPos) && (TextPtr->VPos < HighSelectVPos))
9084 bool SelectVectorNamedElement =
false;
9085 AnsiString SelectTextString;
9090 SelectVectorNamedElement =
true;
9094 if(SelectVectorNamedElement)
9096 SelectTextString =
"##**" + TextPtr->TextString;
9100 SelectTextString = TextPtr->TextString;
9102 TTextItem TextItem(TextPtr->HPos, TextPtr->VPos, SelectTextString, TextPtr->Font);
9111 for(TTrack::TUserGraphicVector::iterator UserGraphicPtr =
Track->
UserGraphicVector.begin(); UserGraphicPtr < Track->UserGraphicVector.end();
9114 if((UserGraphicPtr->HPos >= LowSelectHPos) && ((UserGraphicPtr->HPos + UserGraphicPtr->Width) < HighSelectHPos) && (UserGraphicPtr->VPos >=
9115 LowSelectVPos) && ((UserGraphicPtr->VPos + UserGraphicPtr->Height) < HighSelectVPos))
9154 int MidHPosAfterRotate = ((
SelectRect.bottom * 16) - 1) + (
SelectRect.left * 16) - MidVPosBeforeRotate;
9161 Screen->Cursor = TCursor(-2);
9166 catch(
const Exception &e)
9180 Screen->Cursor = TCursor(-11);
9197 int button = Application->MessageBox
9198 (L
"Original selection adjusted to make it square. 'OK' to keep this selection or 'Cancel' to make a new selection",
9199 L
"Left click and hold here to move this message box", MB_OKCANCEL);
9200 if(button == IDCANCEL)
9208 Screen->Cursor = TCursor(-2);
9245 if(IATVecPair.second != IATVecPair.first)
9263 if((TextPtr->HPos >= LowSelectHPos) && (TextPtr->HPos < HighSelectHPos) && (TextPtr->VPos >= LowSelectVPos) && (TextPtr->VPos < HighSelectVPos))
9270 bool SelectVectorNamedElement =
false;
9271 AnsiString SelectTextString;
9276 SelectVectorNamedElement =
true;
9280 if(SelectVectorNamedElement)
9282 SelectTextString =
"##**" + TextPtr->TextString;
9286 SelectTextString = TextPtr->TextString;
9288 TTextItem TextItem(TextPtr->HPos, TextPtr->VPos, SelectTextString, TextPtr->Font);
9297 for(TTrack::TUserGraphicVector::iterator UserGraphicPtr =
Track->
UserGraphicVector.begin(); UserGraphicPtr < Track->UserGraphicVector.end();
9300 if((UserGraphicPtr->HPos >= LowSelectHPos) && ((UserGraphicPtr->HPos + UserGraphicPtr->Width) < HighSelectHPos) && (UserGraphicPtr->VPos >=
9301 LowSelectVPos) && ((UserGraphicPtr->VPos + UserGraphicPtr->Height) < HighSelectVPos))
9341 int MidVPosAfterRotate = ((
SelectRect.bottom * 16) - 1) + (
SelectRect.left * 16) - MidHPosBeforeRotate;
9347 Screen->Cursor = TCursor(-2);
9352 catch(
const Exception &e)
9372 catch(
const Exception &e)
9391 catch(
const Exception &e)
9409 InfoPanel->Caption =
"DISTANCE/SPEED SETTING: Set values or leave blank for no change";
9412 ShowMessage(
"Note: length value will apply to each element's track within the selection\n\nThis message will only be shown once");
9422 catch(
const Exception &e)
9440 bool FoundFlag =
false;
9484 catch(
const Exception &e)
9514 catch(
const Exception &e)
9541 bool CheckLocationsExistInRailwayTrue =
true;
9545 Screen->Cursor = TCursor(-11);
9546 std::ifstream TTBLFile(AnsiString(
TimetableDialog->FileName).c_str(), std::ios_base::binary);
9547 if(TTBLFile.is_open())
9549 bool SessionFileFalse =
false;
9557 ShowMessage(
"Failed to open timetable file, make sure it's not open in another application");
9559 Screen->Cursor = TCursor(-2);
9562 ShowMessage(
"Timetable preliminary integrity check failed - unable to load");
9567 catch(
const Exception &e)
9592 AnsiString LocName =
"";
9597 if((LocName ==
"") && (Train.
MidElement > -1))
9617 if((NextElementPosition > -1) && (NextEntryPos > -1))
9632 if((LocName ==
"") && (Train.
MidElement > -1))
9639 catch(
const Exception &e)
9663 AnsiString LocName =
"";
9668 if((LocName ==
"") && (Train.
MidElement > -1))
9676 if((LocName ==
"") && (Train.
MidElement > -1))
9706 int NextElementPos = -1;
9707 int NextEntryPos = -1;
9723 if((NextElementPos > -1) && (NextEntryPos > -1))
9757 catch(
const Exception &e)
9775 AnsiString LocName =
"";
9780 if((LocName ==
"") && (Train.
MidElement > -1))
9788 if((LocName ==
"") && (Train.
MidElement > -1))
9795 catch(
const Exception &e)
9824 int NextElementPos = -1;
9825 int NextEntryPos = -1;
9831 if((NextElementPos > -1) && (NextEntryPos > -1))
9851 catch(
const Exception &e)
9864 TTrain *TrainToBeJoinedBy;
9877 ShowMessage(
"Can't join two trains when both are without power");
9881 AnsiString TrainToBeJoinedByHeadCode = TrainToBeJoinedBy->
HeadCode;
9883 double OtherBrakeForce = TrainToBeJoinedBy->
MaxBrakeRate * TrainToBeJoinedBy->
Mass;
9885 double CombinedBrakeRate = (OtherBrakeForce + OwnBrakeForce) / (TrainToBeJoinedBy->
Mass + ThisTrain.
Mass);
9886 ThisTrain.
Mass += TrainToBeJoinedBy->
Mass;
9893 AnsiString LocName =
"";
9898 if((LocName ==
"") && (ThisTrain.
MidElement > -1))
9906 if((LocName ==
"") && (ThisTrain.
MidElement > -1))
9940 catch(
const Exception &e)
9970 AnsiString LocName =
"";
9975 if((LocName ==
"") && (Train.
MidElement > -1))
9983 if((LocName ==
"") && (Train.
MidElement > -1))
9999 catch(
const Exception &e)
10030 catch(
const Exception &e)
10046 if(NextElementPos < 0)
10048 throw Exception(
"Error, no element in front in PassRedSignalMenuItemClick");
10059 throw Exception(
"Error, next element not a signal type in PassRedSignalMenuItemClick");
10073 catch(
const Exception &e)
10099 int NextElementPos = -1;
10101 int NextEntryPos = -1;
10107 if((NextElementPos > -1) && (NextEntryPos > -1))
10116 catch(
const Exception &e)
10135 UnicodeString Message = UnicodeString(Train.
HeadCode) +
" will be removed from the railway - proceed?";
10136 int button = Application->MessageBox(Message.c_str(), L
"Please confirm", MB_YESNO);
10149 AnsiString LocName =
"";
10154 if((LocName ==
"") && (Train.
MidElement > -1))
10162 if((LocName ==
"") && (Train.
MidElement > -1))
10260 catch(
const Exception &e)
10275 Application->Terminate();
10289 catch(
const Exception &e)
10303 UnicodeString MessageStr =
10304 "Note that leaving the track unlinked will cause preferred directions to be lost on reloading. Prevent by linking the track then resaving. Do you still wish to exit?";
10305 int button = Application->MessageBox(MessageStr.c_str(), L
"Please confirm", MB_YESNO);
10315 UnicodeString MessStr =
"";
10318 MessStr = UnicodeString(
"The railway and the timetable have both changed, exit without saving either?");
10322 MessStr = UnicodeString(
"The railway has changed, exit without saving?");
10326 MessStr = UnicodeString(
"The timetable has changed, exit without saving?");
10328 int button = Application->MessageBox(MessStr.c_str(), L
"Please confirm", MB_YESNO);
10341 UnicodeString MessageStr =
"Please note that the session will be lost if it hasn't been saved. Do you still wish to exit?";
10344 int button = Application->MessageBox(MessageStr.c_str(), L
"Please confirm", MB_YESNO);
10363 catch(
const Exception &e)
10377 if((Shift.Contains(ssAlt)) && (Shift.Contains(ssCtrl)))
10390 else if(Key ==
'3')
10402 else if(Key ==
'4')
10406 else if(Key ==
'5')
10408 TMsgDlgButtons Buttons;
10409 Buttons << mbYes << mbNo;
10410 if(MessageDlg(
"Do you wish to allow facing signals next to bridges? If so please be aware that routes cannot be truncated to these signals.", mtWarning, Buttons, 0) == mrYes)
10420 else if(Shift.Contains(ssCtrl) && !Shift.Contains(ssShift) && !Shift.Contains(ssAlt))
10424 else if(Shift.Contains(ssShift) && !Shift.Contains(ssCtrl) && !Shift.Contains(ssAlt))
10437 if((Key != VK_SHIFT) && (Key != VK_CONTROL))
10454 else if(Key == VK_DOWN)
10459 else if(Key == VK_LEFT)
10464 else if(Key == VK_RIGHT)
10469 else if(Key == VK_HOME)
10475 else if(Key == VK_END)
10480 else if(Key == VK_END)
10494 if(Shift.Contains(ssShift) && !Shift.Contains(ssAlt) && !Shift.Contains(ssCtrl) &&
NewHomeButton->Enabled &&
NewHomeButton->Visible)
10505 if(!Shift.Contains(ssCtrl))
10564 if(Key ==
'S' || Key ==
's')
10575 if(Shift.Contains(ssShift))
10591 if(Shift.Contains(ssShift) && !Shift.Contains(ssCtrl) && !Shift.Contains(ssAlt))
10638 if(Shift.Contains(ssCtrl) && !Shift.Contains(ssShift) && !Shift.Contains(ssAlt))
10643 if(Key ==
'S' || Key ==
's')
10649 if(!Shift.Contains(ssCtrl) && !Shift.Contains(ssShift) && !Shift.Contains(ssAlt))
10661 if(!Shift.Contains(ssShift) && !Shift.Contains(ssCtrl))
10668 if(!Shift.Contains(ssShift) && Shift.Contains(ssCtrl))
10673 if(Key ==
'S' || Key ==
's')
10679 if(Shift.Contains(ssShift) && !Shift.Contains(ssCtrl))
10700 if(!Shift.Contains(ssShift) && !Shift.Contains(ssCtrl))
10707 if(Shift.Contains(ssShift) && !Shift.Contains(ssCtrl))
10713 if(Key ==
'S' || Key ==
's')
10718 else if(Key ==
'H' || Key ==
'h')
10732 if(Shift.Contains(ssShift) && !Shift.Contains(ssCtrl))
10802 if(
SaveTTButton->Enabled && (Key ==
'T' || Key ==
't'))
10827 if(
FloatingInfoMenu->Enabled && !Shift.Contains(ssAlt) && Shift.Contains(ssCtrl) && Shift.Contains(ssShift))
10829 if(Key ==
'I' || Key ==
'i')
10835 if(Key ==
'S' || Key ==
's')
10839 else if(Key ==
'T' || Key ==
't')
10849 catch(
const Exception &e)
10859 if((Key != VK_SHIFT) && (Key != VK_CONTROL))
10979 catch(
const Exception &e)
10992 Application->HelpKeyword(u
"Introduction");
10994 catch(
const Exception &e)
11004 const UnicodeString Link =
"http://www.railwayoperationsimulator.com";
11005 ::ShellExecute(Handle, NULL, (Link).c_str(), NULL, NULL, SW_SHOWNORMAL);
11016 std::ofstream ColFile((
CurDir +
"\\Background.col").c_str());
11040 catch(
const Exception &e)
11054 std::ofstream ColFile((
CurDir +
"\\Background.col").c_str());
11057 ShowMessage(
"Failed to store colour file, program will default to a black background when next loaded");
11077 catch(
const Exception &e)
11091 std::ofstream ColFile((
CurDir +
"\\Background.col").c_str());
11094 ShowMessage(
"Failed to store colour file, program will default to a black background when next loaded");
11114 catch(
const Exception &e)
11170 bool ErrorFlag =
false, TooBigFlag =
false;
11191 if(!ErrorFlag && !TooBigFlag)
11201 int KPH = (MPH * 1.609344) + 0.5;
11208 int MPH = (KPH * 0.621371) + 0.5;
11219 catch(
const EConvertError &ec)
11223 catch(
const Exception &e)
11258 bool ErrorFlag =
false, TooBigFlag =
false;
11279 if(!ErrorFlag && !TooBigFlag)
11289 int KW = (HP * 0.745699872) + 0.5;
11296 int HP = (KW * 1.340482574) + 0.5;
11307 catch(
const EConvertError &ec)
11311 catch(
const Exception &e)
11324 bool ErrorFlag =
false, TooBigFlag =
false;
11345 if(!ErrorFlag && !TooBigFlag)
11355 int KPH = (MPH * 1.609344) + 0.5;
11362 int MPH = (KPH * 0.621371) + 0.5;
11373 catch(
const EConvertError &ec)
11377 catch(
const Exception &e)
11391 bool ErrorFlag =
false, TooLongFlag =
false;
11394 for(
int x = 1; x <=
MileEdit->Text.Length(); x++)
11406 for(
int x = 1; x <=
ChainEdit->Text.Length(); x++)
11418 for(
int x = 1; x <=
YardEdit->Text.Length(); x++)
11430 TooLongFlag =
true;
11433 if(!ErrorFlag && !TooLongFlag)
11435 int Miles = 0, Chains = 0, Yards = 0, Metres = 0;
11448 Metres = int((Miles * 1609.344) + (Chains * 20.1168) + (Yards * 0.9144) + 0.5);
11457 catch(
const EConvertError &ec)
11461 catch(
const Exception &e)
11492 catch(
const Exception &e)
11528 "Changes have been made to the timetable clock - you may wish to save a session before resuming operation.\n\nTo cancel all changes re-click the 'Adjust the timetable clock' button then click the reset button BEFORE resuming operation.";
11535 catch(
const Exception &e)
11553 catch(
const Exception &e)
11572 catch(
const Exception &e)
11591 catch(
const Exception &e)
11610 catch(
const Exception &e)
11629 catch(
const Exception &e)
11648 catch(
const Exception &e)
11667 catch(
const Exception &e)
11686 catch(
const Exception &e)
11704 catch(
const Exception &e)
11718 double TTClockIncrement = 1.0 / 24;
11724 catch(
const Exception &e)
11738 double TTClockIncrement = 1.0 / 144;
11744 catch(
const Exception &e)
11758 double TTClockIncrement = 1.0 / 1440;
11764 catch(
const Exception &e)
11805 catch(
const Exception &e)
11819 InfoPanel->Caption =
"PRE-START: Presetting automatic signal routes";
11830 Screen->Cursor = TCursor(-11);
11832 bool PointsChanged, AtLeastOneSet =
false;
11833 int LastIteratorValue = 0;
11840 AtLeastOneSet =
true;
11856 ShowMessage(
"No presettable automatic signal routes are available");
11858 Screen->Cursor = TCursor(-2);
11861 catch(
const Exception &e)
11875 int DispW = (
Interface->Width - 64 - 16) / 16;
11877 int DispH = (
Interface->Height - 192) / 16;
11909 catch(
const Exception &e)
11939 catch(
const Exception &e)
11965 SigImagePanel->Caption =
"Signals will be on the right hand side of the track";
11970 std::ofstream SigFile((
CurDir +
"\\Signal.hnd").c_str());
11973 ShowMessage(
"Failed to store right hand signal setting, program will default to left hand signals when next loaded");
11991 SigImagePanel->Caption =
"Signals will be on the left hand side of the track";
11996 std::ofstream SigFile((
CurDir +
"\\Signal.hnd").c_str());
12008 catch(
const Exception &e)
12027 bool TooBigFlag =
false, BadCharsFlag =
false;
12032 for(
int x = 1; x <=
MTBFEditBox->Text.Length(); x++)
12036 BadCharsFlag =
true;
12049 ShowMessage(
"Maximum value allowed is 10,000");
12058 ShowMessage(
"Value must be a whole number with no special characters");
12075 catch(
const Exception &e)
12093 "Values can only be entered or changed in Pre-Start mode\ni.e. after selecting 'Operate railway' but before clicking 'Run'");
12097 catch(
const Exception &e)
12129 catch(
const Exception &e)
12155 catch(
const Exception &e)
12171 catch(
const Exception &e)
12192 catch(
const Exception &e)
12209 catch(
const Exception &e)
12226 catch(
const Exception &e)
12242 ShowMessage(
"No boxes ticked!");
12246 Screen->Cursor = TCursor(-11);
12247 AnsiString TTTitle;
12261 ShowMessage(
"Analysis complete and file created");
12266 Screen->Cursor = TCursor(-2);
12269 catch(
const Exception &e)
12311 int WidthNum = int(
MainScreen->Width / 160) + 1;
12312 int HeightNum = int(
MainScreen->Height / 144) + 1;
12313 for(
int x = 0; x < WidthNum; x++)
12315 for(
int y = 0; y < HeightNum; y++)
12428 bool BreakFlag =
false;
12515 ZoomButton->Glyph->LoadFromResourceName(0,
"ZoomOut");
12541 InfoPanel->Caption =
"CONNECTING GAPS: Click on connecting element";
12557 UnicodeString MessageStr =
"The railway has changed, close it without saving?";
12558 int button = Application->MessageBox(MessageStr.c_str(), L
"Please confirm", MB_YESNO);
12605 std::ifstream VecFile(FileName);
12607 if(VecFile.is_open())
12627 bool GraphicsFollow =
false;
12628 int NumberOfActiveElements;
12641 if(!(EveryPrefDir->CheckOnePrefDir(0, NumberOfActiveElements, VecFile)))
12672 TDateTime First, Second;
12673 bool Finished =
false;
12675 First = TDateTime::CurrentDateTime();
12676 double TimeVal1 = 86400000 * double(First);
12680 Second = TDateTime::CurrentDateTime();
12681 double TimeVal2 = 86400000 * double(Second);
12682 if((TimeVal2 - TimeVal1) > Msec)
12732 if((LinkNumber1 == 1) || (LinkNumber1 == 3) || (LinkNumber1 == 7) || (LinkNumber1 == 9))
12740 if((LinkNumber2 == 1) || (LinkNumber2 == 3) || (LinkNumber2 == 7) || (LinkNumber2 == 9))
12891 InfoPanel->Caption =
"Select an option from the File, Mode or Help menus";
13045 InfoPanel->Caption =
"PREFERRED DIRECTION SETTING: Select preferred direction start location (right click to erase)";
13107 MTBFLabel->Caption =
"Mean time between\ntrain failures in\ntimetable hours";
13121 OperateButton->Glyph->LoadFromResourceName(0,
"RunGraphic");
13148 ShowMessage(
"Performance logfile failed to open, logs won't be saved. Ensure that there is a folder named " +
PERFLOG_DIR_NAME +
13149 " in the folder where the 'Railway.exe' program file resides");
13190 OAListBox->Items->Add(L
"to locate train");
13195 OAListBox->Items->Add(L
"Left click and");
13196 OAListBox->Items->Add(L
"hold grey area");
13197 OAListBox->Items->Add(L
"to move panel");
13227 OperateButton->Glyph->LoadFromResourceName(0,
"RunGraphic");
13250 OAListBox->Items->Add(L
"to locate train");
13255 OAListBox->Items->Add(L
"Left click and");
13256 OAListBox->Items->Add(L
"hold grey area");
13257 OAListBox->Items->Add(L
"to move panel");
13271 MTBFLabel->Caption =
"Mean time between\ntrain failures in\ntimetable hours";
13280 MTBFLabel->Caption =
"Mean time between\ntrain failures in\ntimetable hours";
13317 InfoPanel->Caption =
"ADDING TRACK: Select element then left click to add it. Right click an element to remove it.";
13337 InfoPanel->Caption =
"ADDING GRAPHIC: Left click layout to add SELECTED graphic, right click to remove ANY graphic.";
13342 InfoPanel->Caption =
"SELECTING USER GRAPHIC: Select the graphic file then add as many as necessary to the layout.";
13346 int HLoc, VLoc, Count;
13348 if(div(Count, 2).rem == 1)
13350 ShowMessage(
"Can't connect, there are an odd number of gaps");
13365 ShowMessage(
"Error - Even number of gaps but all set after first call to HighLightOneGap");
13375 InfoPanel->Caption =
"CONNECTING GAPS: Click on connecting gap";
13382 InfoPanel->Caption =
"ADDING/EDITING TEXT: Left click to add, right click first letter to erase, or left click first letter to edit)";
13397 InfoPanel->Caption =
"MOVING TEXT OR GRAPHIC: If text left click first letter, if graphic left click anywhere, then drag";
13404 InfoPanel->Caption =
"NAMING LOCATIONS: Click on location element to add or change name";
13412 InfoPanel->Caption =
"DISTANCE/SPEED SETTING: Select first location (only non-default elements marked)";
13423 InfoPanel->Caption =
"DISTANCE/SPEED SETTING: Select next location";
13425 InfoPanel->Caption =
"DISTANCE/SPEED SETTING: Continue or set values (overall length), or right click to cancel/truncate";
13437 InfoPanel->Caption =
"SELECTING: Select area - click left mouse && drag";
13447 InfoPanel->Caption =
"COPYING: Left click in selection && drag";
13471 bool EraseSuccessfulFlag, NeedToLink =
false, TextChangesMade =
false, GraphicChangesMade =
false; ;
13472 int ErasedTrackVectorPosition;
13473 Screen->Cursor = TCursor(-11);
13475 InfoPanel->Caption =
"CUT PROCESSING: Please do not click the mouse";
13482 if(EraseSuccessfulFlag)
13484 if(ErasedTrackVectorPosition > -1)
13494 int HighSelectVPos =
SelectRect.bottom * 16;
13500 if((TextPtr->HPos >= LowSelectHPos) && (TextPtr->HPos < HighSelectHPos) && (TextPtr->VPos >= LowSelectVPos) && (TextPtr->VPos <
13506 TextChangesMade =
true;
13516 if((GraphicPtr->HPos >= LowSelectHPos) && ((GraphicPtr->HPos + GraphicPtr->Width) < HighSelectHPos) && (GraphicPtr->VPos >= LowSelectVPos)
13517 && ((GraphicPtr->VPos + GraphicPtr->Height) < HighSelectVPos))
13520 GraphicChangesMade =
true;
13527 Screen->Cursor = TCursor(-2);
13532 InfoPanel->Caption =
"CUTTING: Left click in selection && drag";
13548 if(NeedToLink || TextChangesMade || GraphicChangesMade)
13563 bool NeedToLink =
false;
13564 bool TrackLinkingRequiredFlag;
13565 Screen->Cursor = TCursor(-11);
13567 InfoPanel->Caption =
"PASTING: Please wait";
13574 bool TrackEraseSuccessfulFlag;
13575 int ErasedTrackVectorPosition;
13577 for(
int x = LowSelectHLoc; x < HighSelectHLoc; x++)
13579 for(
int y = LowSelectVLoc; y < HighSelectVLoc; y++)
13582 if(ErasedTrackVectorPosition > -1)
13597 if((TextPtr->HPos >= LowSelectHPos) && (TextPtr->HPos < HighSelectHPos) && (TextPtr->VPos >= LowSelectVPos) && (TextPtr->VPos <
13612 if((GraphicPtr->HPos >= LowSelectHPos) && ((GraphicPtr->HPos + GraphicPtr->Width) < HighSelectHPos) && (GraphicPtr->VPos >= LowSelectVPos)
13613 && ((GraphicPtr->VPos + GraphicPtr->Height) < HighSelectVPos))
13634 bool InternalChecks =
false;
13638 TrackLinkingRequiredFlag, InternalChecks);
13654 if(TrackLinkingRequiredFlag)
13662 TextPtr->HPos += HDiff * 16;
13663 TextPtr->VPos += VDiff * 16;
13664 AnsiString TempString = TextPtr->TextString;
13680 if(TextPtr->TextString.SubString(1, 4) ==
"##**")
13682 TempString = TextPtr->TextString.SubString(5, TextPtr->TextString.Length());
13685 TextPtr->TextString =
"";
13697 for(TTrack::TUserGraphicVector::iterator GraphicPtr =
Track->
SelectGraphicVector.begin(); GraphicPtr < Track->SelectGraphicVector.end();
13700 GraphicPtr->HPos += HDiff * 16;
13701 GraphicPtr->VPos += VDiff * 16;
13714 Screen->Cursor = TCursor(-2);
13728 UnicodeString MessageStr =
"Selected area will be deleted - proceed?";
13729 int button = Application->MessageBox(MessageStr.c_str(), L
"Please confirm", MB_YESNO);
13734 bool EraseSuccessfulFlag, NeedToLink =
false, TextChangesMade =
false, GraphicChangesMade =
false;
13735 int ErasedTrackVectorPosition;
13736 Screen->Cursor = TCursor(-11);
13738 InfoPanel->Caption =
"DELETING: Please wait";
13745 if(EraseSuccessfulFlag)
13747 if(ErasedTrackVectorPosition > -1)
13757 int HighSelectVPos =
SelectRect.bottom * 16;
13763 AnsiString Check = TextPtr->TextString;
13764 if((TextPtr->HPos >= LowSelectHPos) && (TextPtr->HPos < HighSelectHPos) && (TextPtr->VPos >= LowSelectVPos) && (TextPtr->VPos <
13770 TextChangesMade =
true;
13789 if((GraphicPtr->HPos >= LowSelectHPos) && ((GraphicPtr->HPos + GraphicPtr->Width) < HighSelectHPos) && (GraphicPtr->VPos >= LowSelectVPos)
13790 && ((GraphicPtr->VPos + GraphicPtr->Height) < HighSelectVPos))
13795 if((UserGraphicPtr->HPos == GraphicPtr->HPos) && (UserGraphicPtr->VPos == GraphicPtr->VPos) &&
13796 (UserGraphicPtr->Width == GraphicPtr->Width) && (UserGraphicPtr->Height == GraphicPtr->Height) &&
13797 (UserGraphicPtr->FileName == GraphicPtr->FileName))
13800 GraphicChangesMade =
true;
13817 if(NeedToLink || TextChangesMade || GraphicChangesMade)
13821 Screen->Cursor = TCursor(-2);
13873 bool LeadingPointsAtLastElement =
false;
13876 if(LeadingPointsAtLastElement)
13878 InfoPanel->Caption =
"PREFERRED DIRECTION SETTING: Can't end on leading points, select next location or truncate";
13883 InfoPanel->Caption =
"PREFERRED DIRECTION SETTING: Select next preferred direction location (right click to truncate)";
13888 InfoPanel->Caption =
"PREFERRED DIRECTION SETTING: Add selection or select next location (right click to truncate)";
13903 InfoPanel->Caption =
"SELECTING: Select area - click left mouse && drag";
13943 OperateButton->Glyph->LoadFromResourceName(0,
"PauseGraphic");
13986 Display->
PerformanceLog(15, TimeMessage +
"Timetable clock speed changed to one sixteenth normal");
13991 if(TTClockTimeChange > 0.000347)
13994 int MinsIncrease = ((TTClockTimeChange * 1440) + 0.5);
13995 int HoursIncrease = 0;
13996 while(MinsIncrease >= 60)
13999 MinsIncrease -= 60;
14001 if(HoursIncrease == 0)
14002 TimeMessage +=
"Timetable clock incremented by " + AnsiString(MinsIncrease) +
"m";
14003 else if(MinsIncrease == 0)
14004 TimeMessage +=
"Timetable clock incremented by " + AnsiString(HoursIncrease) +
"h";
14006 TimeMessage +=
"Timetable clock incremented by " + AnsiString(HoursIncrease) +
"h " + AnsiString(MinsIncrease) +
"m";
14017 MTBFLabel->Caption =
"Mean time between\ntrain failures in\ntimetable hours";
14025 MTBFLabel->Caption =
"Mean time between\ntrain failures in\ntimetable hours";
14034 OperateButton->Glyph->LoadFromResourceName(0,
"RunGraphic");
14062 float LockDelay = 120.0;
14068 bool BreakFlag =
false;
14072 if((TTClockTime - LRVIT->LockStartTime) > TDateTime(LockDelay / 86400))
14075 AnsiString(LRVIT->LastTrackVectorPosition));
14076 while(Route.
LastElementPtr(9)->GetTrackVectorPosition() != LRVIT->TruncateTrackVectorPosition)
14089 if(Route.
LastElementPtr(17)->GetTrackVectorPosition() == LRVIT->TruncateTrackVectorPosition)
14128 int TempLockedVectorNumber;
14138 if(((TTClockTime - AutoSigVectorIT->PassoutTime) > TDateTime(AutoSigVectorIT->FirstDelay / 86400)) && (AutoSigVectorIT->AccessNumber == 0))
14141 AutoSigVectorIT->AccessNumber++;
14144 if(((TTClockTime - AutoSigVectorIT->PassoutTime) > TDateTime(AutoSigVectorIT->SecondDelay / 86400)) && (AutoSigVectorIT->AccessNumber == 1))
14147 AutoSigVectorIT->AccessNumber++;
14150 if(((TTClockTime - AutoSigVectorIT->PassoutTime) > TDateTime(AutoSigVectorIT->ThirdDelay / 86400)) && (AutoSigVectorIT->AccessNumber == 2))
14153 AutoSigVectorIT->AccessNumber++;
14161 if(AutoSigVectorIT->AccessNumber > 2)
14176 TPoint MousePoint = Mouse->CursorPos;
14177 int ScreenX = MousePoint.x -
MainScreen->ClientOrigin.x;
14178 int ScreenY = MousePoint.y -
MainScreen->ClientOrigin.y;
14180 if((ScreenX > (
MainScreen->Width - 1)) || (ScreenY > (
MainScreen->Height - 1)) || (ScreenX < 0) || (ScreenY < 0))
14190 ((MousePoint.y - ClientOrigin.y) >=
PerformancePanel->Top) && ((MousePoint.y - ClientOrigin.y) <=
14202 ((MousePoint.y - ClientOrigin.y) >=
OperatorActionPanel->Top) && ((MousePoint.y - ClientOrigin.y) <=
14214 ((MousePoint.y - ClientOrigin.y) >=
TimetableEditPanel->Top) && ((MousePoint.y - ClientOrigin.y) <=
14223 AnsiString TrackFloat =
"", TrainStatusFloat =
"", TrainTTFloat =
"";
14225 bool ShowTrackFloatFlag =
false, ShowTrainStatusFloatFlag =
false, ShowTrainTTFloatFlag =
false;
14237 bool ActiveTrackFoundFlag =
false, InactiveTrackFoundFlag =
false, TwoTrack =
false;
14238 AnsiString Length01Str =
"", Length23Str =
"", SpeedLimit01Str =
"", SpeedLimit23Str =
"";
14239 AnsiString StationEntryStopLinkPos1Str =
"", StationEntryStopLinkPos2Str =
"";
14240 AnsiString ATrackSN =
"", ATrackTN =
"", IATrackSN =
"", LengthAndSpeedCaption =
"";
14241 AnsiString SigAspectString =
"";
14245 if(InactiveTrackFoundFlag)
14250 if(ActiveTrackFoundFlag)
14257 if((ATrackTN !=
"") && (!InactiveTrackFoundFlag || ((InactiveTrackElement.
TrackType !=
Platform) &&
14261 ShowMessage(
"Error - Track has timetable name without corresponding plat/named loc");
14266 ShowMessage(
"Error - plat/named loc and track have different names, or plat/named loc named but not track");
14272 Length01Str = AnsiString(ActiveTrackElement.
Length01);
14273 if(Length01Str ==
"-1")
14274 Length01Str =
"Not Set";
14275 SpeedLimit01Str = AnsiString(ActiveTrackElement.
SpeedLimit01);
14276 if(SpeedLimit01Str ==
"-1")
14277 SpeedLimit01Str =
"Not Set";
14280 Length23Str = AnsiString(ActiveTrackElement.
Length23);
14281 if(Length23Str ==
"-1")
14282 Length23Str =
"Not Set";
14283 SpeedLimit23Str = AnsiString(ActiveTrackElement.
SpeedLimit23);
14284 if(SpeedLimit23Str ==
"-1")
14285 SpeedLimit23Str =
"Not Set";
14288 LengthAndSpeedCaption =
"Straight track length = " + Length01Str +
" m" +
'\n' +
"Diverging track length = " + Length23Str +
" m" +
'\n' +
14289 "Straight track speed limit = " + SpeedLimit01Str +
" km/h" +
'\n' +
"Diverging track speed limit = " + SpeedLimit23Str +
" km/h";
14293 LengthAndSpeedCaption =
"Left diverging track length = " + Length01Str +
" m" +
'\n' +
"Right diverging track length = " + Length23Str +
14294 " m" +
'\n' +
"Left diverging track speed limit = " + SpeedLimit01Str +
" km/h" +
'\n' +
"Right diverging track Speed Limit = " +
14295 SpeedLimit23Str +
" km/h";
14300 if((ActiveTrackElement.
SpeedTag == 15) || (ActiveTrackElement.
SpeedTag == 46))
14302 LengthAndSpeedCaption =
"Horizontal track length = " + Length01Str +
" m" +
'\n' +
"Other track length = " + Length23Str +
" m" +
'\n' +
14303 "Horizontal track speed limit = " + SpeedLimit01Str +
" km/h" +
'\n' +
"Other track speed limit = " + SpeedLimit23Str +
" km/h";
14305 else if(ActiveTrackElement.
SpeedTag == 47)
14307 LengthAndSpeedCaption =
"Horizontal track length = " + Length23Str +
" m" +
'\n' +
"Other track length = " + Length01Str +
" m" +
'\n' +
14308 "Horizontal track speed limit = " + SpeedLimit23Str +
" km/h" +
'\n' +
"Other track speed limit = " + SpeedLimit01Str +
" km/h";
14310 else if(ActiveTrackElement.
SpeedTag == 45)
14312 LengthAndSpeedCaption =
"Vertical track length = " + Length01Str +
" m" +
'\n' +
"Other track length = " + Length23Str +
" m" +
'\n' +
14313 "Vertical track speed limit = " + SpeedLimit01Str +
" km/h" +
'\n' +
"Other track speed limit = " + SpeedLimit23Str +
" km/h";
14315 else if(ActiveTrackElement.
SpeedTag == 44)
14317 LengthAndSpeedCaption =
"Vertical track length = " + Length23Str +
" m" +
'\n' +
"Other track length = " + Length01Str +
" m" +
'\n' +
14318 "Vertical track speed limit = " + SpeedLimit23Str +
" km/h" +
'\n' +
"Other track speed limit = " + SpeedLimit01Str +
" km/h";
14320 else if(ActiveTrackElement.
SpeedTag == 16)
14322 LengthAndSpeedCaption =
"Top left to bottom right track length = " + Length01Str +
" m" +
'\n' +
"Other track length = " + Length23Str +
14323 " m" +
'\n' +
"Top left to bottom right track speed limit = " + SpeedLimit01Str +
" km/h" +
'\n' +
"Other track speed limit = " +
14324 SpeedLimit23Str +
" km/h";
14329 LengthAndSpeedCaption =
"Top track length = " + Length01Str +
" m" +
'\n' +
"Bottom track length = " + Length23Str +
" m" +
'\n' +
14330 "Top track speed limit = " + SpeedLimit01Str +
" km/h" +
'\n' +
"Bottom track speed limit = " + SpeedLimit23Str +
" km/h";
14335 LengthAndSpeedCaption =
"Track length = " + Length01Str +
" m" +
'\n' +
"Track speed limit = " + SpeedLimit01Str +
" km/h";
14338 if(ActiveTrackFoundFlag)
14342 ShowTrackFloatFlag =
true;
14345 TrackFloat =
"Location = " + ATrackTN +
'\n' + LengthAndSpeedCaption +
'\n' +
"ID = " + AnsiString(ActiveTrackElement.
ElementID);
14347 else if(ATrackSN !=
"")
14349 TrackFloat =
"Location = " + ATrackSN +
'\n' + LengthAndSpeedCaption +
'\n' +
"ID = " + AnsiString(ActiveTrackElement.
ElementID);
14352 else if(InactiveTrackFoundFlag)
14354 TrackFloat =
"Location unnamed\n" + LengthAndSpeedCaption +
'\n' +
"ID = " + AnsiString(ActiveTrackElement.
ElementID);
14359 TrackFloat = LengthAndSpeedCaption +
'\n' +
"Track Element ID = " + AnsiString(ActiveTrackElement.
ElementID);
14365 SigAspectString =
"\nThree-aspect signal";
14369 SigAspectString =
"\nTwo-aspect signal";
14373 SigAspectString =
"\nGround signal";
14377 SigAspectString =
"\nFour-aspect signal";
14379 TrackFloat += SigAspectString;
14382 else if(InactiveTrackFoundFlag)
14385 ShowTrackFloatFlag =
true;
14388 if(IATrackSN ==
"")
14390 TrackFloat =
"Location unnamed\nID = " + AnsiString(InactiveTrackElement.
ElementID);
14394 TrackFloat =
"Location = " + IATrackSN +
'\n' +
"ID = " + AnsiString(InactiveTrackElement.
ElementID);
14399 TrackFloat =
"ID = " + AnsiString(InactiveTrackElement.
ElementID);
14409 AnsiString FormatOneDPStr =
"####0.0";
14410 AnsiString FormatNoDPStr =
"#######0";
14412 AnsiString MaxBrakeStr =
"";
14413 AnsiString SpecialStr =
"", MaxSpeedStr =
"";
14423 ShowTrainStatusFloatFlag =
true;
14424 AnsiString HeadCode =
"", ServiceReferenceInfo =
"", Status =
"", CurrSpeedStr =
"", BrakePCStr =
"", NextStopStr =
"", TimeLeftStr =
"",
14425 TimeToNextMovementStr =
"", MassStr =
"", PowerStr =
"";
14427 MassStr = AnsiString::FormatFloat(FormatNoDPStr, ((
double)Train.
Mass) / 1000);
14428 PowerStr = AnsiString::FormatFloat(FormatNoDPStr, Train.
PowerAtRail / 1000 / 0.8);
14430 MaxSpeedStr =
"30";
14432 MaxSpeedStr = AnsiString::FormatFloat(FormatNoDPStr, Train.
MaxRunningSpeed);
14436 TDateTime TimeLeft;
14438 MaxBrakeStr = AnsiString::FormatFloat(FormatNoDPStr, (Train.
MaxBrakeRate * Train.
Mass / 9810));
14447 ServiceReferenceInfo =
"\nFirst service";
14450 ServiceReferenceInfo =
"\nRepeat service no. " + AnsiString(Train.
RepeatNumber);
14452 ServiceReferenceInfo =
"\nRepeat service no. " + AnsiString(Train.
RepeatNumber) +
" of ref. " +
14463 Status =
"Stopped on signaller's instruction";
14465 Status =
"Not in service";
14467 Status =
"Stopped at buffers";
14469 Status =
"Stopped at signal";
14471 Status =
"Stopped - forward track occupied";
14479 Status =
"Stopped without power - train failed";
14481 Status =
"Stopped without power";
14484 Status =
"Stopped - signal passed at danger";
14486 Status =
"Derailed";
14488 Status =
"Crashed";
14495 Status =
"Accelerating";
14502 if(BrakePCRate < 55)
14503 Status =
"Light braking";
14504 else if(BrakePCRate < 90)
14505 Status =
"Heavy braking";
14507 Status =
"Emergency braking";
14513 if(BrakePCRate < 55)
14514 Status =
"Light braking";
14515 else if(BrakePCRate < 90)
14516 Status =
"Heavy braking";
14518 Status =
"Emergency braking";
14524 Status =
"Accelerating";
14530 Status =
"Accelerating";
14532 ((Train.
ExitSpeedFull - Train.
ExitSpeedHalf) * (
double(ElapsedDeltaT - FirstHalfTimeDeltaT) / double(SecondHalfTimeDeltaT)));
14541 Status =
"Coasting - train failed";
14545 Status =
"Coasting - no power";
14551 Status =
"Constant speed";
14562 Status =
"Coasting - train failed";
14566 Status =
"Coasting - no power";
14572 Status =
"Constant speed";
14579 NextStopStr =
"At signaller's discretion";
14581 NextStopStr =
"None";
14587 SpecialStr =
"Train under signaller control" + AnsiString(
'\n');
14591 SpecialStr =
"Restricted speed - being called on" + AnsiString(
'\n');
14595 if(RemTimeHalf < 0)
14598 if(RemTimeFull < 0)
14600 if(RemTimeHalf > 0)
14601 TimeLeft = RemTimeHalf;
14603 TimeLeft = RemTimeFull;
14604 TimeToNextMovementStr =
"Time to next movement (sec) = " + TimeLeftStr.FormatFloat(FormatOneDPStr, TimeLeft);
14606 TimeToNextMovementStr =
"";
14610 MaxSpeedStr +
"km/h; Power " + PowerStr +
"kW" +
'\n' +
"Mass " + MassStr +
"Te; Brakes " + MaxBrakeStr +
"Te" +
'\n' + SpecialStr +
14611 Status +
'\n' +
"Next: " + NextStopStr;
14616 MaxSpeedStr +
"km/h; Power " + PowerStr +
"kW" +
'\n' +
"Mass " + MassStr +
"Te; Brakes " + MaxBrakeStr +
"Te" +
'\n' + SpecialStr +
14617 Status +
": " + CurrSpeedStr.FormatFloat(FormatNoDPStr, CurrSpeed) +
"km/h" +
'\n' +
"Next: " + NextStopStr;
14622 ShowTrainTTFloatFlag =
true;
14631 TrainStatusFloat =
"No trains expected";
14632 TrainTTFloat =
"No timetable";
14636 ShowTrainStatusFloatFlag =
true;
14638 ShowTrainTTFloatFlag =
true;
14645 (CTEIt->second.TrainDataEntryPtr->TrainOperatingDataVector.at(CTEIt->second.RepeatNumber).RunningEntry !=
NotStarted)))
14652 AnsiString ServiceReferenceInfo =
"";
14656 if(CTEIt->second.RepeatNumber == 0)
14659 ServiceReferenceInfo =
"\nFirst service of ref. " + TTDEPtr->
ServiceReference;
14661 ServiceReferenceInfo =
"\nFirst service";
14664 ServiceReferenceInfo =
"\nRepeat service no. " + AnsiString(CTEIt->second.RepeatNumber);
14666 ServiceReferenceInfo =
"\nRepeat service no. " + AnsiString(CTEIt->second.RepeatNumber) +
" of ref. " +
14672 ServiceReferenceInfo =
"\nService reference " + TTDEPtr->
ServiceReference;
14676 SpecialStr =
"\nTrain under signaller control";
14678 if(EntrySpeed > LineSpeedLimit)
14679 EntrySpeed = LineSpeedLimit;
14684 if(EntrySpeed > LineSpeedLimit)
14685 EntrySpeed = LineSpeedLimit;
14689 TDateTime TempTime = CTEIt->first;
14691 TrainStatusFloat = CTEIt->second.HeadCode +
": " + CTEIt->second.Description + ServiceReferenceInfo +
"\nEntry speed " +
14692 AnsiString::FormatFloat(FormatNoDPStr, EntrySpeed) +
"km/h" + SpecialStr +
"\nDelayed, was due at " +
14697 TDateTime TempTime = CTEIt->first;
14699 TrainStatusFloat = CTEIt->second.HeadCode +
": " + CTEIt->second.Description + ServiceReferenceInfo +
"\nEntry speed " +
14700 AnsiString::FormatFloat(FormatNoDPStr, EntrySpeed) +
"km/h" + SpecialStr +
"\nExpected at " +
14708 CTEIt->second.IncrementalMinutes, CTEIt->second.IncrementalDigits);
14719 AnsiString Caption;
14721 if(!ShowTrackFloatFlag && !ShowTrainStatusFloatFlag && !ShowTrainTTFloatFlag)
14727 else if(ShowTrackFloatFlag && !ShowTrainStatusFloatFlag && !ShowTrainTTFloatFlag)
14729 Caption = TrackFloat;
14731 else if(!ShowTrackFloatFlag && ShowTrainStatusFloatFlag && !ShowTrainTTFloatFlag)
14733 Caption = TrainStatusFloat;
14735 else if(ShowTrackFloatFlag && ShowTrainStatusFloatFlag && !ShowTrainTTFloatFlag)
14737 Caption = TrainStatusFloat +
'\n' +
'\n' + TrackFloat;
14739 else if(!ShowTrackFloatFlag && !ShowTrainStatusFloatFlag && ShowTrainTTFloatFlag)
14741 if(TrainStatusFloat ==
"No trains expected")
14742 Caption = TrainStatusFloat;
14744 Caption = TrainTTFloat;
14746 else if(ShowTrackFloatFlag && !ShowTrainStatusFloatFlag && ShowTrainTTFloatFlag)
14748 if(TrainStatusFloat ==
"No trains expected")
14749 Caption = TrainStatusFloat +
'\n' +
'\n' + TrackFloat;
14751 Caption = TrainTTFloat +
'\n' +
'\n' + TrackFloat;
14753 else if(!ShowTrackFloatFlag && ShowTrainStatusFloatFlag && ShowTrainTTFloatFlag)
14755 if(TrainStatusFloat ==
"No trains expected")
14756 Caption = TrainStatusFloat;
14758 Caption = TrainStatusFloat +
'\n' +
'\n' + TrainTTFloat;
14760 else if(ShowTrackFloatFlag && ShowTrainStatusFloatFlag && ShowTrainTTFloatFlag)
14762 if(TrainStatusFloat ==
"No trains expected")
14763 Caption = TrainStatusFloat +
'\n' +
'\n' + TrackFloat;
14765 Caption = TrainStatusFloat +
'\n' +
'\n' + TrainTTFloat +
'\n' +
'\n' + TrackFloat;
14863 InfoPanel->Caption =
"PRE-START: Route setting in progress";
14865 InfoPanel->Caption =
"OPERATING: Route setting in progress";
15028 throw Exception(
"Failed to find a route at LC position HLoc = " + (AnsiString)H +
" VLoc = " + (AnsiString)V);
15033 if(RouteNumber > -1)
15067 bool SaveRailwayButtonsFlag =
true;
15076 SaveRailwayButtonsFlag =
false;
15093 SaveRailwayButtonsFlag =
false;
15101 SaveRailwayButtonsFlag =
false;
15154 bool ZoomFlag =
true, HomeFlag =
true, NewHomeFlag =
true, ScreenLeftFlag =
true, ScreenRightFlag =
true, ScreenUpFlag =
true, ScreenDownFlag =
true,
15155 TrackBuildPanelEnabledFlag =
true, PrefDirPanelEnabledFlag =
true, OperatingPanelEnabledFlag =
true, TimetablePanelEnabledFlag =
true;
15157 AnsiString TrackBuildPanelLabelCaptionStr =
"Build/modify";
15158 AnsiString PrefDirPanelLabelCaptionStr =
"Preferred direction selection";
15159 AnsiString OperatingPanelLabelCaptionStr =
"Operation";
15160 AnsiString TimetablePanelLabelCaptionStr =
"Timetable editor";
15165 ScreenLeftFlag =
false;
15167 ScreenRightFlag =
false;
15169 ScreenUpFlag =
false;
15171 ScreenDownFlag =
false;
15176 ScreenLeftFlag =
false;
15178 ScreenRightFlag =
false;
15180 ScreenUpFlag =
false;
15182 ScreenDownFlag =
false;
15188 NewHomeFlag =
false;
15189 ScreenLeftFlag =
false;
15190 ScreenRightFlag =
false;
15191 ScreenUpFlag =
false;
15192 ScreenDownFlag =
false;
15198 TrackBuildPanelEnabledFlag =
false;
15199 TrackBuildPanelLabelCaptionStr =
"Disabled";
15200 PrefDirPanelEnabledFlag =
false;
15201 PrefDirPanelLabelCaptionStr =
"Disabled";
15202 OperatingPanelEnabledFlag =
false;
15203 OperatingPanelLabelCaptionStr =
"Disabled";
15204 TimetablePanelEnabledFlag =
false;
15205 TimetablePanelLabelCaptionStr =
"Disabled";
15213 OperatingPanelEnabledFlag =
false;
15214 OperatingPanelLabelCaptionStr =
"Disabled";
15217 NewHomeFlag =
false;
15218 ScreenLeftFlag =
false;
15219 ScreenRightFlag =
false;
15220 ScreenUpFlag =
false;
15221 ScreenDownFlag =
false;
15235 NewHomeFlag =
false;
15236 ScreenLeftFlag =
false;
15237 ScreenRightFlag =
false;
15238 ScreenUpFlag =
false;
15239 ScreenDownFlag =
false;
15246 NewHomeFlag =
false;
15247 ScreenLeftFlag =
false;
15248 ScreenRightFlag =
false;
15249 ScreenUpFlag =
false;
15250 ScreenDownFlag =
false;
15258 NewHomeFlag =
false;
15259 ScreenLeftFlag =
false;
15260 ScreenRightFlag =
false;
15261 ScreenUpFlag =
false;
15262 ScreenDownFlag =
false;
15287 if(ScreenRightFlag)
15299 if(OperatingPanelEnabledFlag)
15303 if(TrackBuildPanelEnabledFlag)
15307 if(PrefDirPanelEnabledFlag)
15311 if(TimetablePanelEnabledFlag)
15330 bool CallOnValid =
false;
15336 CallOnValid =
true;
15428 Screen->Cursor = TCursor(-2);
15471 Caption =
"Railway: New railway under development";
15473 Caption =
"Railway: " +
RailwayTitle +
" under development";
15562 TFont *TempFont =
new TFont;
15564 TempFont->Style.Clear();
15565 TempFont->Name =
"MS Sans Serif";
15566 TempFont->Size = 10;
15568 TempFont->Charset = (TFontCharset)(0);
15674 if(NonPrefDirChangesMade)
15698 AnsiString CurrentDateTimeStr =
"", TimetableTimeStr =
"", SessionFileStr =
"";
15699 Screen->Cursor = TCursor(-11);
15700 CurrentDateTimeStr = TDateTime::CurrentDateTime().FormatString(
"dd-mm-yyyy hh.nn.ss");
15703 TimetableTimeStr = TimetableTimeStr.SubString(1, 2) +
'.' + TimetableTimeStr.SubString(4, 2) +
'.' + TimetableTimeStr.SubString(7, 2);
15706 std::ofstream SessionFile(SessionFileStr.c_str());
15707 if(!(SessionFile.fail()))
15749 SessionFile.close();
15750 DeleteFile(SessionFileStr);
15751 Screen->Cursor = TCursor(-2);
15783 SessionFile.close();
15791 " in the folder where the 'Railway.exe' program file resides");
15794 Screen->Cursor = TCursor(-2);
15797 catch(
const Exception &e)
15826 Screen->Cursor = TCursor(-11);
15831 if(!(SessionFile.fail()))
15838 int LastCharBeforeFloat = TempString.LastDelimiter(
'*');
15839 if((LastCharBeforeFloat == 0) || (LastCharBeforeFloat == TempString.Length()))
15846 AnsiString FloatStr = TempString.SubString(LastCharBeforeFloat + 1, TempString.Length() - LastCharBeforeFloat);
15862 bool GraphicsFollow =
false;
15878 SessionFile.close();
15879 Screen->Cursor = TCursor(-2);
15880 ShowMessage(
"Corruption in preferred direction section of the session file, session can't be loaded");
15888 SessionFile.close();
15889 Screen->Cursor = TCursor(-2);
15890 ShowMessage(
"Corruption in route section of the session file, session can't be loaded");
15902 if(TempString ==
"***BarriersDownVector***")
15910 SessionFile.close();
15911 Screen->Cursor = TCursor(-2);
15912 ShowMessage(
"Unable to load timetable section of the session file, session can't be loaded");
15919 SessionFile.close();
15920 Screen->Cursor = TCursor(-2);
15921 throw Exception(
"TimetableTitle null in LoadSession");
15939 ShowMessage(
"Performance logfile failed to open, logs won't be saved. Ensure that there is a folder named " +
PERFLOG_DIR_NAME +
15940 " in the folder where the 'Railway.exe' program file resides");
15946 SessionFile.get(TempChar);
15947 while(!SessionFile.eof() && ((TempChar ==
'\n') || (TempChar ==
'\0')))
15949 SessionFile.get(TempChar);
15951 if(SessionFile.eof())
15955 SessionFile.close();
15966 double PowerDouble;
15974 SessionFile.close();
16010 ShowMessage(
"Session file integrity check failed, unable to load session.");
16012 Screen->Cursor = TCursor(-2);
16016 catch(
const Exception &e)
16018 if((e.Message.Pos(
"esource") > 0) || (e.Message.Pos(
"arameter") > 0))
16020 Screen->Cursor = TCursor(-2);
16031 UnicodeString MessageStr =
16032 "Insufficient memory available to load the file, and partial load likely to be corrupt. Application will terminate. Try loading the session as the first action after reloading the program.";
16034 Application->MessageBox(MessageStr.c_str(), L
"Out of memory", MB_OK | MB_ICONERROR);
16035 Application->Terminate();
16106 if(OpMode ==
"PreStart")
16164 AnsiString OpMode =
"";
16171 else if((OpMode !=
"PreStart") && (OpMode !=
"NotPreStart"))
16403 SessionFile.close();
16404 SessionFile.open(SessionFileStr.c_str(), std::ios_base::app | std::ios_base::binary);
16418 ShowMessage(
"Failed to open temporary timetable file. Unable to save the session");
16424 char *Buffer =
new char[10000];
16429 BytesRead = FileRead(Handle, Buffer, 10000);
16430 SessionFile.write(Buffer, BytesRead);
16431 if(BytesRead < 10000)
16437 SessionFile.close();
16438 SessionFile.open(SessionFileStr.c_str(), std::ios_base::app | std::ios_base::out);
16462 if(!FileExists(TimetableFileName))
16469 ErrorFile.open(ErrorFileStr.c_str(), std::ios_base::app | std::ios_base::binary);
16471 int Handle = FileOpen(TimetableFileName, fmOpenRead);
16478 Handle = FileOpen(TimetableFileName, fmOpenRead);
16488 char *Buffer =
new char[10000];
16493 BytesRead = FileRead(Handle, Buffer, 10000);
16494 ErrorFile.write(Buffer, BytesRead);
16495 if(BytesRead < 10000)
16502 ErrorFile.open(ErrorFileStr.c_str(), std::ios_base::app | std::ios_base::out);
16530 int TempTTFileNumber = 0;
16532 while(FileExists(
CurDir +
"\\TmpTT" + AnsiString(TempTTFileNumber) +
".tmp"))
16534 TempTTFileNumber++;
16542 if(!TTBFile.fail())
16544 char *Buffer =
new char[10000];
16545 char TempChar = (char)(SessionFile.peek());
16546 if(TempChar ==
'\n')
16547 SessionFile.get(TempChar);
16548 if(!SessionFile.getline(Buffer, 10000,
'\0'))
16557 for(
int x = 0; x < 10000; x++)
16559 if(Buffer[x] !=
'\0')
16564 while(AnsiString(Buffer) !=
"***End***")
16566 TTBFile.write(Buffer, Count);
16567 TTBFile.write(&Zero, 1);
16569 if(!SessionFile.getline(Buffer, 10000,
'\0'))
16578 for(
int x = 0; x < 10000; x++)
16580 if(Buffer[x] !=
'\0')
16590 bool GiveMessagesFalse =
false;
16591 bool CheckLocationsExistInRailwayTrue =
true;
16594 std::ifstream TTBLFile(
TempTTFileName.c_str(), std::ios_base::binary);
16595 if(TTBLFile.is_open())
16597 bool SessionFileTrue =
true;
16628 for(
int x = 0; x < NumberOfTrainEntries; x++)
16636 for(
int y = 0; y < NumberOfTrains; y++)
16661 AnsiString OutString;
16668 while(OutString !=
"***End***")
16677 if(SessionFile.fail())
16682 int NumberOfTrainEntries;
16689 for(
int x = 0; x < NumberOfTrainEntries; x++)
16691 int NumberOfTrains;
16697 for(
int y = 0; y < NumberOfTrains; y++)
16726 bool EndOfFile =
false;
16728 char *TrainTimetableString =
new char[10000];
16732 TTBLFile.getline(TrainTimetableString, 10000,
'\0');
16733 if(TTBLFile.eof() && (TrainTimetableString[0] ==
'\0'))
16739 AnsiString OneLine(TrainTimetableString);
16740 bool FinalCallTrue =
true;
16742 CheckLocationsExistInRailway))
16744 TTBLFile.getline(TrainTimetableString, 10000,
'\0');
16745 if(TTBLFile.eof() && (TrainTimetableString[0] ==
'\0'))
16748 throw Exception(
"Timetable FinalCall error - no start time on own line, Count = 0");
16750 OneLine = AnsiString(TrainTimetableString);
16756 TTBLFile.getline(TrainTimetableString, 10000,
'\0');
16757 if(TTBLFile.eof() && (TrainTimetableString[0] ==
'\0'))
16763 OneLine = AnsiString(TrainTimetableString);
16768 throw Exception(
"Timetable FinalCall error in processing one timetable line, Count = " + AnsiString(Count));
16770 if(EndOfFile && (Count < 2))
16773 throw Exception(
"Timetable FinalCall error - too few or no relevant entries, Count = " + AnsiString(Count));
16778 delete TrainTimetableString;
16785 ShowMessage(
"Timetable secondary integrity check failed - unable to load");
16821 bool EndOfFile =
false;
16823 char *TrainTimetableString =
new char[10000];
16827 TTBLFile.getline(TrainTimetableString, 10000,
'\0');
16828 if(TTBLFile.eof() && (TrainTimetableString[0] ==
'\0'))
16834 AnsiString OneLine(TrainTimetableString);
16835 bool FinalCallTrue =
true;
16837 CheckLocationsExistInRailway))
16839 TTBLFile.getline(TrainTimetableString, 10000,
'\0');
16840 if(TTBLFile.eof() && (TrainTimetableString[0] ==
'\0'))
16843 throw Exception(
"Timetable FinalCall error - no start time on own line, Count = 0");
16845 OneLine = AnsiString(TrainTimetableString);
16851 TTBLFile.getline(TrainTimetableString, 10000,
'\0');
16852 if(TTBLFile.eof() && (TrainTimetableString[0] ==
'\0'))
16858 OneLine = AnsiString(TrainTimetableString);
16863 throw Exception(
"Timetable FinalCall error in processing one timetable line, Count = " + AnsiString(Count));
16865 if(EndOfFile && (Count < 2))
16868 throw Exception(
"Timetable FinalCall error - too few or no relevant entries, Count = " + AnsiString(Count));
16873 delete TrainTimetableString;
16905 std::ifstream InFile(FileName.c_str());
16907 int NumberOfActiveElements;
16908 bool GraphicsFollow =
false;
16910 if(InFile.is_open())
17057 if((TempString !=
"***BarriersDownVector***") && (TempString !=
"***Timetable***"))
17063 if(TempString ==
"***BarriersDownVector***")
17101 ShowMessage(
"Session file failed to open, unable to load session. Ensure that there is a folder named " +
SESSION_DIR_NAME +
17102 " in the folder where the 'Railway.exe' program file resides");
17109 InFile.open(FileName.c_str());
17110 if(InFile.is_open())
17131 bool GraphicsFollow =
false;
17252 if((TempString !=
"***BarriersDownVector***") && (TempString !=
"***Timetable***"))
17258 if(TempString ==
"***BarriersDownVector***")
17337 InFile.get(TempChar);
17338 while(!InFile.eof() && ((TempChar ==
'\n') || (TempChar ==
'\0')))
17340 InFile.get(TempChar);
17371 double PowerDouble;
17401 AnsiString TempString =
"", Line1 =
"", Line2 =
"", Line3 =
"", Line4 =
"", Line5 =
"";
17402 char *Buffer =
new char[1000];
17405 InFile.get(TempChar);
17406 InFile.getline(Buffer, 1000);
17407 TempString = AnsiString(Buffer);
17408 while(TempString !=
"***End of performance file***")
17412 InFile.getline(Buffer, 1000);
17413 TempString = AnsiString(Buffer);
17424 AnsiString TempString =
"";
17427 InFile.get(TempChar);
17428 if(TempChar !=
'\n')
17438 while(TempString !=
"***End of performance file***")
17459 AnsiString OneLine = Text.SubString(1, Text.Pos(
'\x0D'));
17460 while((OneLine.Length() > 0) && OneLine[OneLine.Length()] <
' ')
17461 OneLine.SetLength(OneLine.Length() - 1);
17462 Text = Text.SubString(Text.Pos(
'\x0D'), Text.Length());
17463 while((Text.Length() > 0) && Text[1] <
' ')
17464 Text = Text.SubString(2, (Text.Length() - 1));
17465 OutFile << OneLine.c_str() <<
'\n';
17484 InfoPanel->Caption =
"PRE-START: Select AUTOMATIC SIGNAL ROUTE start signal, or left click points to change manually";
17486 InfoPanel->Caption =
"OPERATING: Select AUTOMATIC SIGNAL ROUTE start signal, or left click points to change manually";
17496 InfoPanel->Caption =
"PRE-START: Select PREFERRED ROUTE start signal, or left click points to change manually";
17498 InfoPanel->Caption =
"OPERATING: Select PREFERRED ROUTE start signal, or left click points to change manually";
17508 InfoPanel->Caption =
"PRE-START: Select UNRESTRICTED ROUTE start location, or left click points to change manually";
17510 InfoPanel->Caption =
"OPERATING: Select UNRESTRICTED ROUTE start location, or left click points to change manually";
17521 InfoPanel->Caption =
"PRE-START: Select UNRESTRICTED ROUTE start location, or left click points to change manually";
17523 InfoPanel->Caption =
"OPERATING: Select UNRESTRICTED ROUTE start location, or left click points to change manually";
17549 InfoPanel->Caption =
"Left click screen to zoom in at that position";
17554 InfoPanel->Caption =
"PAUSED: Railway state changes disabled";
17627 Screen->Cursor = TCursor(-11);
17628 AnsiString ErrorFileStr =
CurDir +
"\\errorlog.err";
17629 std::ofstream ErrorFile(ErrorFileStr.c_str());
17631 if(!(ErrorFile.fail()))
17634 int ScreenX = Mouse->CursorPos.x -
MainScreen->ClientOrigin.x;
17635 int ScreenY = Mouse->CursorPos.y -
MainScreen->ClientOrigin.y;
17636 AnsiString MouseStr =
"Posx: " + AnsiString(ScreenX) +
"; Posy: " + AnsiString(ScreenY);
17646 ErrorFile << Item.c_str() <<
'\n';
17653 ErrorFile << Item.c_str() <<
'\n';
17762 Screen->Cursor = TCursor(-2);
17779 int TempTTFileNumber = 0;
17781 while(FileExists(
CurDir +
"\\TmpTT" + AnsiString(TempTTFileNumber) +
".tmp"))
17783 TempTTFileNumber++;
17786 int InHandle = FileOpen(InFileName, fmOpenRead);
17789 while(InHandle < 0)
17791 InHandle = FileOpen(InFileName, fmOpenRead);
17796 ShowMessage(
"Failed to open timetable file, make sure it's not open in another application");
17804 while(OutHandle < 0)
17811 ShowMessage(
"Failed to save temporary timetable file, sessions can't be saved - try again, may only be a temporary problem");
17812 FileClose(InHandle);
17817 int CountIn, CountOut;
17818 char *Buffer =
new char[10000];
17822 CountIn = FileRead(InHandle, Buffer, 10000);
17823 CountOut = FileWrite(OutHandle, Buffer, CountIn);
17824 if(CountOut != CountIn)
17826 ShowMessage(
"Error in writing to the temporary timetable file, sessions can't be saved - try again, may only be a temporary problem");
17828 FileClose(InHandle);
17829 FileClose(OutHandle);
17833 if(CountIn < 10000)
17837 FileClose(InHandle);
17838 FileClose(OutHandle);
17883 int VarElements = 0;
17884 bool NamedLocPresent =
false;
17892 throw Exception(
"Error - failed to find track element at " + AnsiString(TE.
HLoc) +
" & " + AnsiString(TE.
VLoc) +
" in SetLengths");
17899 NamedLocPresent =
true;
17905 if(SpeedLimit != -1)
17910 if(SpeedLimit != -1)
17920 if((NamedLocPresent) && (VarElements > 0) && ((Distance / VarElements) < 50))
17922 ShowMessage(
"Note: Named location elements are quite short. If they are too short the simulation might depart too far from reality.");
17925 if((NamedLocPresent) && (VarElements > 0) && ((Distance / VarElements) > 200))
17927 ShowMessage(
"Note: Named location elements are quite long. If they are too long the simulation might depart too far from reality.");
17936 if((VarElements * 20) > Distance)
17938 ShowMessage(
"Required distance is less than the minimum, will set each element to the minimum (20m)");
17939 Distance = (VarElements * 20);
17941 if(VarElements == 0)
17944 ShowMessage(
"No elements selected");
17950 int RemainingDistance = Distance, RemainingVarElements = VarElements, NextLength = RemainingDistance / VarElements;
17958 if(NextLength < 20)
17982 RemainingDistance -= NextLength;
17983 RemainingVarElements--;
17984 if(RemainingVarElements > 0)
17985 NextLength = RemainingDistance / RemainingVarElements;
18010 ShowMessage(
"Nothing to save!");
18015 SaveRailwayDialog->Filter =
"Development file (*.dev)|*.dev|Railway file (*.rly)|*.rly";
18021 Screen->Cursor = TCursor(-11);
18023 AnsiString Extension =
"";
18031 if(!(VecFile.fail()))
18059 if((LastChar ==
'y') || (LastChar ==
'Y'))
18087 ShowMessage(
"File open failed prior to save");
18091 ShowMessage(
"Can't save: extension must be either '.dev', or '.rly' with railway ready for operation");
18093 Screen->Cursor = TCursor(-2);
18191 bool TextFound =
false;
18214 AnsiString(VPos) +
"," + AnsiString((
short)UseEnteredPosition));
18215 int VPosHi, VPosLo, TextPosHi, TextPosLo;
18218 if(!UseEnteredPosition)
18225 int Depth = abs(Font->Height);
18226 TextPosHi = VPosHi + 20;
18227 TextPosLo = VPosLo - Depth - 4;
18230 if(TextPosLo >= ScreenPosLo)
18232 else if(TextPosHi < ScreenPosHi)
18235 VPos = ScreenPosLo + 288;
18281 catch(
const Exception &e)
18358 AnsiString OpTimeToActDisplay;
18359 AnsiString OpTimeToActString;
18360 AnsiString HeadCode;
18361 float OpTimeToActFloat;
18373 HeadCode = HCandTrainPosParam.first;
18374 if(OpTimeToActFloat < 0.25)
18376 OpTimeToActString =
"NOW";
18378 else if(OpTimeToActFloat < 1)
18380 OpTimeToActString =
"<1";
18384 OpTimeToActString = AnsiString(floor(OpTimeToActFloat));
18386 if(OpTimeToActFloat < 60)
18388 OpTimeToActDisplay = HeadCode + AnsiString(
'\t') + OpTimeToActString;
18389 OAListBox->Items->Add(OpTimeToActDisplay);
18414 TPicture *PicPtr =
new TPicture;
18416 UGME.second = PicPtr;
18427 catch(
const EInvalidGraphic &e)
18430 "Incorrect file format, the file can't be loaded.\nEnsure that the file you want is a valid graphic file with extension .bmp, .gif, .jpg, or .png");
18432 catch(
const Exception &e)